123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- """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
- @classmethod
- 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])
|