boson.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. """Bosonic quantum operators."""
  2. from sympy.core.mul import Mul
  3. from sympy.core.numbers import Integer
  4. from sympy.core.singleton import S
  5. from sympy.functions.elementary.complexes import conjugate
  6. from sympy.functions.elementary.exponential import exp
  7. from sympy.functions.elementary.miscellaneous import sqrt
  8. from sympy.physics.quantum import Operator
  9. from sympy.physics.quantum import HilbertSpace, FockSpace, Ket, Bra, IdentityOperator
  10. from sympy.functions.special.tensor_functions import KroneckerDelta
  11. __all__ = [
  12. 'BosonOp',
  13. 'BosonFockKet',
  14. 'BosonFockBra',
  15. 'BosonCoherentKet',
  16. 'BosonCoherentBra'
  17. ]
  18. class BosonOp(Operator):
  19. """A bosonic operator that satisfies [a, Dagger(a)] == 1.
  20. Parameters
  21. ==========
  22. name : str
  23. A string that labels the bosonic mode.
  24. annihilation : bool
  25. A bool that indicates if the bosonic operator is an annihilation (True,
  26. default value) or creation operator (False)
  27. Examples
  28. ========
  29. >>> from sympy.physics.quantum import Dagger, Commutator
  30. >>> from sympy.physics.quantum.boson import BosonOp
  31. >>> a = BosonOp("a")
  32. >>> Commutator(a, Dagger(a)).doit()
  33. 1
  34. """
  35. @property
  36. def name(self):
  37. return self.args[0]
  38. @property
  39. def is_annihilation(self):
  40. return bool(self.args[1])
  41. @classmethod
  42. def default_args(self):
  43. return ("a", True)
  44. def __new__(cls, *args, **hints):
  45. if not len(args) in [1, 2]:
  46. raise ValueError('1 or 2 parameters expected, got %s' % args)
  47. if len(args) == 1:
  48. args = (args[0], S.One)
  49. if len(args) == 2:
  50. args = (args[0], Integer(args[1]))
  51. return Operator.__new__(cls, *args)
  52. def _eval_commutator_BosonOp(self, other, **hints):
  53. if self.name == other.name:
  54. # [a^\dagger, a] = -1
  55. if not self.is_annihilation and other.is_annihilation:
  56. return S.NegativeOne
  57. elif 'independent' in hints and hints['independent']:
  58. # [a, b] = 0
  59. return S.Zero
  60. return None
  61. def _eval_commutator_FermionOp(self, other, **hints):
  62. return S.Zero
  63. def _eval_anticommutator_BosonOp(self, other, **hints):
  64. if 'independent' in hints and hints['independent']:
  65. # {a, b} = 2 * a * b, because [a, b] = 0
  66. return 2 * self * other
  67. return None
  68. def _eval_adjoint(self):
  69. return BosonOp(str(self.name), not self.is_annihilation)
  70. def __mul__(self, other):
  71. if other == IdentityOperator(2):
  72. return self
  73. if isinstance(other, Mul):
  74. args1 = tuple(arg for arg in other.args if arg.is_commutative)
  75. args2 = tuple(arg for arg in other.args if not arg.is_commutative)
  76. x = self
  77. for y in args2:
  78. x = x * y
  79. return Mul(*args1) * x
  80. return Mul(self, other)
  81. def _print_contents_latex(self, printer, *args):
  82. if self.is_annihilation:
  83. return r'{%s}' % str(self.name)
  84. else:
  85. return r'{{%s}^\dagger}' % str(self.name)
  86. def _print_contents(self, printer, *args):
  87. if self.is_annihilation:
  88. return r'%s' % str(self.name)
  89. else:
  90. return r'Dagger(%s)' % str(self.name)
  91. def _print_contents_pretty(self, printer, *args):
  92. from sympy.printing.pretty.stringpict import prettyForm
  93. pform = printer._print(self.args[0], *args)
  94. if self.is_annihilation:
  95. return pform
  96. else:
  97. return pform**prettyForm('\N{DAGGER}')
  98. class BosonFockKet(Ket):
  99. """Fock state ket for a bosonic mode.
  100. Parameters
  101. ==========
  102. n : Number
  103. The Fock state number.
  104. """
  105. def __new__(cls, n):
  106. return Ket.__new__(cls, n)
  107. @property
  108. def n(self):
  109. return self.label[0]
  110. @classmethod
  111. def dual_class(self):
  112. return BosonFockBra
  113. @classmethod
  114. def _eval_hilbert_space(cls, label):
  115. return FockSpace()
  116. def _eval_innerproduct_BosonFockBra(self, bra, **hints):
  117. return KroneckerDelta(self.n, bra.n)
  118. def _apply_operator_BosonOp(self, op, **options):
  119. if op.is_annihilation:
  120. return sqrt(self.n) * BosonFockKet(self.n - 1)
  121. else:
  122. return sqrt(self.n + 1) * BosonFockKet(self.n + 1)
  123. class BosonFockBra(Bra):
  124. """Fock state bra for a bosonic mode.
  125. Parameters
  126. ==========
  127. n : Number
  128. The Fock state number.
  129. """
  130. def __new__(cls, n):
  131. return Bra.__new__(cls, n)
  132. @property
  133. def n(self):
  134. return self.label[0]
  135. @classmethod
  136. def dual_class(self):
  137. return BosonFockKet
  138. @classmethod
  139. def _eval_hilbert_space(cls, label):
  140. return FockSpace()
  141. class BosonCoherentKet(Ket):
  142. """Coherent state ket for a bosonic mode.
  143. Parameters
  144. ==========
  145. alpha : Number, Symbol
  146. The complex amplitude of the coherent state.
  147. """
  148. def __new__(cls, alpha):
  149. return Ket.__new__(cls, alpha)
  150. @property
  151. def alpha(self):
  152. return self.label[0]
  153. @classmethod
  154. def dual_class(self):
  155. return BosonCoherentBra
  156. @classmethod
  157. def _eval_hilbert_space(cls, label):
  158. return HilbertSpace()
  159. def _eval_innerproduct_BosonCoherentBra(self, bra, **hints):
  160. if self.alpha == bra.alpha:
  161. return S.One
  162. else:
  163. return exp(-(abs(self.alpha)**2 + abs(bra.alpha)**2 - 2 * conjugate(bra.alpha) * self.alpha)/2)
  164. def _apply_operator_BosonOp(self, op, **options):
  165. if op.is_annihilation:
  166. return self.alpha * self
  167. else:
  168. return None
  169. class BosonCoherentBra(Bra):
  170. """Coherent state bra for a bosonic mode.
  171. Parameters
  172. ==========
  173. alpha : Number, Symbol
  174. The complex amplitude of the coherent state.
  175. """
  176. def __new__(cls, alpha):
  177. return Bra.__new__(cls, alpha)
  178. @property
  179. def alpha(self):
  180. return self.label[0]
  181. @classmethod
  182. def dual_class(self):
  183. return BosonCoherentKet
  184. def _apply_operator_BosonOp(self, op, **options):
  185. if not op.is_annihilation:
  186. return self.alpha * self
  187. else:
  188. return None