Spaces:
Sleeping
Sleeping
| """The anti-commutator: ``{A,B} = A*B + B*A``.""" | |
| from sympy.core.expr import Expr | |
| from sympy.core.mul import Mul | |
| from sympy.core.numbers import Integer | |
| from sympy.core.singleton import S | |
| from sympy.printing.pretty.stringpict import prettyForm | |
| from sympy.physics.quantum.operator import Operator | |
| from sympy.physics.quantum.dagger import Dagger | |
| __all__ = [ | |
| 'AntiCommutator' | |
| ] | |
| #----------------------------------------------------------------------------- | |
| # Anti-commutator | |
| #----------------------------------------------------------------------------- | |
| class AntiCommutator(Expr): | |
| """The standard anticommutator, in an unevaluated state. | |
| Explanation | |
| =========== | |
| Evaluating an anticommutator is defined [1]_ as: ``{A, B} = A*B + B*A``. | |
| This class returns the anticommutator in an unevaluated form. To evaluate | |
| the anticommutator, use the ``.doit()`` method. | |
| Canonical ordering of an anticommutator is ``{A, B}`` for ``A < B``. The | |
| arguments of the anticommutator are put into canonical order using | |
| ``__cmp__``. If ``B < A``, then ``{A, B}`` is returned as ``{B, A}``. | |
| Parameters | |
| ========== | |
| A : Expr | |
| The first argument of the anticommutator {A,B}. | |
| B : Expr | |
| The second argument of the anticommutator {A,B}. | |
| Examples | |
| ======== | |
| >>> from sympy import symbols | |
| >>> from sympy.physics.quantum import AntiCommutator | |
| >>> from sympy.physics.quantum import Operator, Dagger | |
| >>> x, y = symbols('x,y') | |
| >>> A = Operator('A') | |
| >>> B = Operator('B') | |
| Create an anticommutator and use ``doit()`` to multiply them out. | |
| >>> ac = AntiCommutator(A,B); ac | |
| {A,B} | |
| >>> ac.doit() | |
| A*B + B*A | |
| The commutator orders it arguments in canonical order: | |
| >>> ac = AntiCommutator(B,A); ac | |
| {A,B} | |
| Commutative constants are factored out: | |
| >>> AntiCommutator(3*x*A,x*y*B) | |
| 3*x**2*y*{A,B} | |
| Adjoint operations applied to the anticommutator are properly applied to | |
| the arguments: | |
| >>> Dagger(AntiCommutator(A,B)) | |
| {Dagger(A),Dagger(B)} | |
| References | |
| ========== | |
| .. [1] https://en.wikipedia.org/wiki/Commutator | |
| """ | |
| is_commutative = False | |
| def __new__(cls, A, B): | |
| r = cls.eval(A, B) | |
| if r is not None: | |
| return r | |
| obj = Expr.__new__(cls, A, B) | |
| return obj | |
| def eval(cls, a, b): | |
| if not (a and b): | |
| return S.Zero | |
| if a == b: | |
| return Integer(2)*a**2 | |
| if a.is_commutative or b.is_commutative: | |
| return Integer(2)*a*b | |
| # [xA,yB] -> xy*[A,B] | |
| ca, nca = a.args_cnc() | |
| cb, ncb = b.args_cnc() | |
| c_part = ca + cb | |
| if c_part: | |
| return Mul(Mul(*c_part), cls(Mul._from_args(nca), Mul._from_args(ncb))) | |
| # Canonical ordering of arguments | |
| #The Commutator [A,B] is on canonical form if A < B. | |
| if a.compare(b) == 1: | |
| return cls(b, a) | |
| def doit(self, **hints): | |
| """ Evaluate anticommutator """ | |
| A = self.args[0] | |
| B = self.args[1] | |
| if isinstance(A, Operator) and isinstance(B, Operator): | |
| try: | |
| comm = A._eval_anticommutator(B, **hints) | |
| except NotImplementedError: | |
| try: | |
| comm = B._eval_anticommutator(A, **hints) | |
| except NotImplementedError: | |
| comm = None | |
| if comm is not None: | |
| return comm.doit(**hints) | |
| return (A*B + B*A).doit(**hints) | |
| def _eval_adjoint(self): | |
| return AntiCommutator(Dagger(self.args[0]), Dagger(self.args[1])) | |
| def _sympyrepr(self, printer, *args): | |
| return "%s(%s,%s)" % ( | |
| self.__class__.__name__, printer._print( | |
| self.args[0]), printer._print(self.args[1]) | |
| ) | |
| def _sympystr(self, printer, *args): | |
| return "{%s,%s}" % ( | |
| printer._print(self.args[0]), printer._print(self.args[1])) | |
| def _pretty(self, printer, *args): | |
| pform = printer._print(self.args[0], *args) | |
| pform = prettyForm(*pform.right(prettyForm(','))) | |
| pform = prettyForm(*pform.right(printer._print(self.args[1], *args))) | |
| pform = prettyForm(*pform.parens(left='{', right='}')) | |
| return pform | |
| def _latex(self, printer, *args): | |
| return "\\left\\{%s,%s\\right\\}" % tuple([ | |
| printer._print(arg, *args) for arg in self.args]) | |