anticommutator.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. """The anti-commutator: ``{A,B} = A*B + B*A``."""
  2. from sympy.core.expr import Expr
  3. from sympy.core.mul import Mul
  4. from sympy.core.numbers import Integer
  5. from sympy.core.singleton import S
  6. from sympy.printing.pretty.stringpict import prettyForm
  7. from sympy.physics.quantum.operator import Operator
  8. from sympy.physics.quantum.dagger import Dagger
  9. __all__ = [
  10. 'AntiCommutator'
  11. ]
  12. #-----------------------------------------------------------------------------
  13. # Anti-commutator
  14. #-----------------------------------------------------------------------------
  15. class AntiCommutator(Expr):
  16. """The standard anticommutator, in an unevaluated state.
  17. Explanation
  18. ===========
  19. Evaluating an anticommutator is defined [1]_ as: ``{A, B} = A*B + B*A``.
  20. This class returns the anticommutator in an unevaluated form. To evaluate
  21. the anticommutator, use the ``.doit()`` method.
  22. Canonical ordering of an anticommutator is ``{A, B}`` for ``A < B``. The
  23. arguments of the anticommutator are put into canonical order using
  24. ``__cmp__``. If ``B < A``, then ``{A, B}`` is returned as ``{B, A}``.
  25. Parameters
  26. ==========
  27. A : Expr
  28. The first argument of the anticommutator {A,B}.
  29. B : Expr
  30. The second argument of the anticommutator {A,B}.
  31. Examples
  32. ========
  33. >>> from sympy import symbols
  34. >>> from sympy.physics.quantum import AntiCommutator
  35. >>> from sympy.physics.quantum import Operator, Dagger
  36. >>> x, y = symbols('x,y')
  37. >>> A = Operator('A')
  38. >>> B = Operator('B')
  39. Create an anticommutator and use ``doit()`` to multiply them out.
  40. >>> ac = AntiCommutator(A,B); ac
  41. {A,B}
  42. >>> ac.doit()
  43. A*B + B*A
  44. The commutator orders it arguments in canonical order:
  45. >>> ac = AntiCommutator(B,A); ac
  46. {A,B}
  47. Commutative constants are factored out:
  48. >>> AntiCommutator(3*x*A,x*y*B)
  49. 3*x**2*y*{A,B}
  50. Adjoint operations applied to the anticommutator are properly applied to
  51. the arguments:
  52. >>> Dagger(AntiCommutator(A,B))
  53. {Dagger(A),Dagger(B)}
  54. References
  55. ==========
  56. .. [1] https://en.wikipedia.org/wiki/Commutator
  57. """
  58. is_commutative = False
  59. def __new__(cls, A, B):
  60. r = cls.eval(A, B)
  61. if r is not None:
  62. return r
  63. obj = Expr.__new__(cls, A, B)
  64. return obj
  65. @classmethod
  66. def eval(cls, a, b):
  67. if not (a and b):
  68. return S.Zero
  69. if a == b:
  70. return Integer(2)*a**2
  71. if a.is_commutative or b.is_commutative:
  72. return Integer(2)*a*b
  73. # [xA,yB] -> xy*[A,B]
  74. ca, nca = a.args_cnc()
  75. cb, ncb = b.args_cnc()
  76. c_part = ca + cb
  77. if c_part:
  78. return Mul(Mul(*c_part), cls(Mul._from_args(nca), Mul._from_args(ncb)))
  79. # Canonical ordering of arguments
  80. #The Commutator [A,B] is on canonical form if A < B.
  81. if a.compare(b) == 1:
  82. return cls(b, a)
  83. def doit(self, **hints):
  84. """ Evaluate anticommutator """
  85. A = self.args[0]
  86. B = self.args[1]
  87. if isinstance(A, Operator) and isinstance(B, Operator):
  88. try:
  89. comm = A._eval_anticommutator(B, **hints)
  90. except NotImplementedError:
  91. try:
  92. comm = B._eval_anticommutator(A, **hints)
  93. except NotImplementedError:
  94. comm = None
  95. if comm is not None:
  96. return comm.doit(**hints)
  97. return (A*B + B*A).doit(**hints)
  98. def _eval_adjoint(self):
  99. return AntiCommutator(Dagger(self.args[0]), Dagger(self.args[1]))
  100. def _sympyrepr(self, printer, *args):
  101. return "%s(%s,%s)" % (
  102. self.__class__.__name__, printer._print(
  103. self.args[0]), printer._print(self.args[1])
  104. )
  105. def _sympystr(self, printer, *args):
  106. return "{%s,%s}" % (
  107. printer._print(self.args[0]), printer._print(self.args[1]))
  108. def _pretty(self, printer, *args):
  109. pform = printer._print(self.args[0], *args)
  110. pform = prettyForm(*pform.right(prettyForm(',')))
  111. pform = prettyForm(*pform.right(printer._print(self.args[1], *args)))
  112. pform = prettyForm(*pform.parens(left='{', right='}'))
  113. return pform
  114. def _latex(self, printer, *args):
  115. return "\\left\\{%s,%s\\right\\}" % tuple([
  116. printer._print(arg, *args) for arg in self.args])