operatorordering.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. """Functions for reordering operator expressions."""
  2. import warnings
  3. from sympy.core.add import Add
  4. from sympy.core.mul import Mul
  5. from sympy.core.numbers import Integer
  6. from sympy.core.power import Pow
  7. from sympy.physics.quantum import Operator, Commutator, AntiCommutator
  8. from sympy.physics.quantum.boson import BosonOp
  9. from sympy.physics.quantum.fermion import FermionOp
  10. __all__ = [
  11. 'normal_order',
  12. 'normal_ordered_form'
  13. ]
  14. def _expand_powers(factors):
  15. """
  16. Helper function for normal_ordered_form and normal_order: Expand a
  17. power expression to a multiplication expression so that that the
  18. expression can be handled by the normal ordering functions.
  19. """
  20. new_factors = []
  21. for factor in factors.args:
  22. if (isinstance(factor, Pow)
  23. and isinstance(factor.args[1], Integer)
  24. and factor.args[1] > 0):
  25. for n in range(factor.args[1]):
  26. new_factors.append(factor.args[0])
  27. else:
  28. new_factors.append(factor)
  29. return new_factors
  30. def _normal_ordered_form_factor(product, independent=False, recursive_limit=10,
  31. _recursive_depth=0):
  32. """
  33. Helper function for normal_ordered_form_factor: Write multiplication
  34. expression with bosonic or fermionic operators on normally ordered form,
  35. using the bosonic and fermionic commutation relations. The resulting
  36. operator expression is equivalent to the argument, but will in general be
  37. a sum of operator products instead of a simple product.
  38. """
  39. factors = _expand_powers(product)
  40. new_factors = []
  41. n = 0
  42. while n < len(factors) - 1:
  43. if isinstance(factors[n], BosonOp):
  44. # boson
  45. if not isinstance(factors[n + 1], BosonOp):
  46. new_factors.append(factors[n])
  47. elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
  48. if (independent and
  49. str(factors[n].name) > str(factors[n + 1].name)):
  50. new_factors.append(factors[n + 1])
  51. new_factors.append(factors[n])
  52. n += 1
  53. else:
  54. new_factors.append(factors[n])
  55. elif not factors[n].is_annihilation:
  56. new_factors.append(factors[n])
  57. else:
  58. if factors[n + 1].is_annihilation:
  59. new_factors.append(factors[n])
  60. else:
  61. if factors[n].args[0] != factors[n + 1].args[0]:
  62. if independent:
  63. c = 0
  64. else:
  65. c = Commutator(factors[n], factors[n + 1])
  66. new_factors.append(factors[n + 1] * factors[n] + c)
  67. else:
  68. c = Commutator(factors[n], factors[n + 1])
  69. new_factors.append(
  70. factors[n + 1] * factors[n] + c.doit())
  71. n += 1
  72. elif isinstance(factors[n], FermionOp):
  73. # fermion
  74. if not isinstance(factors[n + 1], FermionOp):
  75. new_factors.append(factors[n])
  76. elif factors[n].is_annihilation == factors[n + 1].is_annihilation:
  77. if (independent and
  78. str(factors[n].name) > str(factors[n + 1].name)):
  79. new_factors.append(factors[n + 1])
  80. new_factors.append(factors[n])
  81. n += 1
  82. else:
  83. new_factors.append(factors[n])
  84. elif not factors[n].is_annihilation:
  85. new_factors.append(factors[n])
  86. else:
  87. if factors[n + 1].is_annihilation:
  88. new_factors.append(factors[n])
  89. else:
  90. if factors[n].args[0] != factors[n + 1].args[0]:
  91. if independent:
  92. c = 0
  93. else:
  94. c = AntiCommutator(factors[n], factors[n + 1])
  95. new_factors.append(-factors[n + 1] * factors[n] + c)
  96. else:
  97. c = AntiCommutator(factors[n], factors[n + 1])
  98. new_factors.append(
  99. -factors[n + 1] * factors[n] + c.doit())
  100. n += 1
  101. elif isinstance(factors[n], Operator):
  102. if isinstance(factors[n + 1], (BosonOp, FermionOp)):
  103. new_factors.append(factors[n + 1])
  104. new_factors.append(factors[n])
  105. n += 1
  106. else:
  107. new_factors.append(factors[n])
  108. else:
  109. new_factors.append(factors[n])
  110. n += 1
  111. if n == len(factors) - 1:
  112. new_factors.append(factors[-1])
  113. if new_factors == factors:
  114. return product
  115. else:
  116. expr = Mul(*new_factors).expand()
  117. return normal_ordered_form(expr,
  118. recursive_limit=recursive_limit,
  119. _recursive_depth=_recursive_depth + 1,
  120. independent=independent)
  121. def _normal_ordered_form_terms(expr, independent=False, recursive_limit=10,
  122. _recursive_depth=0):
  123. """
  124. Helper function for normal_ordered_form: loop through each term in an
  125. addition expression and call _normal_ordered_form_factor to perform the
  126. factor to an normally ordered expression.
  127. """
  128. new_terms = []
  129. for term in expr.args:
  130. if isinstance(term, Mul):
  131. new_term = _normal_ordered_form_factor(
  132. term, recursive_limit=recursive_limit,
  133. _recursive_depth=_recursive_depth, independent=independent)
  134. new_terms.append(new_term)
  135. else:
  136. new_terms.append(term)
  137. return Add(*new_terms)
  138. def normal_ordered_form(expr, independent=False, recursive_limit=10,
  139. _recursive_depth=0):
  140. """Write an expression with bosonic or fermionic operators on normal
  141. ordered form, where each term is normally ordered. Note that this
  142. normal ordered form is equivalent to the original expression.
  143. Parameters
  144. ==========
  145. expr : expression
  146. The expression write on normal ordered form.
  147. recursive_limit : int (default 10)
  148. The number of allowed recursive applications of the function.
  149. Examples
  150. ========
  151. >>> from sympy.physics.quantum import Dagger
  152. >>> from sympy.physics.quantum.boson import BosonOp
  153. >>> from sympy.physics.quantum.operatorordering import normal_ordered_form
  154. >>> a = BosonOp("a")
  155. >>> normal_ordered_form(a * Dagger(a))
  156. 1 + Dagger(a)*a
  157. """
  158. if _recursive_depth > recursive_limit:
  159. warnings.warn("Too many recursions, aborting")
  160. return expr
  161. if isinstance(expr, Add):
  162. return _normal_ordered_form_terms(expr,
  163. recursive_limit=recursive_limit,
  164. _recursive_depth=_recursive_depth,
  165. independent=independent)
  166. elif isinstance(expr, Mul):
  167. return _normal_ordered_form_factor(expr,
  168. recursive_limit=recursive_limit,
  169. _recursive_depth=_recursive_depth,
  170. independent=independent)
  171. else:
  172. return expr
  173. def _normal_order_factor(product, recursive_limit=10, _recursive_depth=0):
  174. """
  175. Helper function for normal_order: Normal order a multiplication expression
  176. with bosonic or fermionic operators. In general the resulting operator
  177. expression will not be equivalent to original product.
  178. """
  179. factors = _expand_powers(product)
  180. n = 0
  181. new_factors = []
  182. while n < len(factors) - 1:
  183. if (isinstance(factors[n], BosonOp) and
  184. factors[n].is_annihilation):
  185. # boson
  186. if not isinstance(factors[n + 1], BosonOp):
  187. new_factors.append(factors[n])
  188. else:
  189. if factors[n + 1].is_annihilation:
  190. new_factors.append(factors[n])
  191. else:
  192. if factors[n].args[0] != factors[n + 1].args[0]:
  193. new_factors.append(factors[n + 1] * factors[n])
  194. else:
  195. new_factors.append(factors[n + 1] * factors[n])
  196. n += 1
  197. elif (isinstance(factors[n], FermionOp) and
  198. factors[n].is_annihilation):
  199. # fermion
  200. if not isinstance(factors[n + 1], FermionOp):
  201. new_factors.append(factors[n])
  202. else:
  203. if factors[n + 1].is_annihilation:
  204. new_factors.append(factors[n])
  205. else:
  206. if factors[n].args[0] != factors[n + 1].args[0]:
  207. new_factors.append(-factors[n + 1] * factors[n])
  208. else:
  209. new_factors.append(-factors[n + 1] * factors[n])
  210. n += 1
  211. else:
  212. new_factors.append(factors[n])
  213. n += 1
  214. if n == len(factors) - 1:
  215. new_factors.append(factors[-1])
  216. if new_factors == factors:
  217. return product
  218. else:
  219. expr = Mul(*new_factors).expand()
  220. return normal_order(expr,
  221. recursive_limit=recursive_limit,
  222. _recursive_depth=_recursive_depth + 1)
  223. def _normal_order_terms(expr, recursive_limit=10, _recursive_depth=0):
  224. """
  225. Helper function for normal_order: look through each term in an addition
  226. expression and call _normal_order_factor to perform the normal ordering
  227. on the factors.
  228. """
  229. new_terms = []
  230. for term in expr.args:
  231. if isinstance(term, Mul):
  232. new_term = _normal_order_factor(term,
  233. recursive_limit=recursive_limit,
  234. _recursive_depth=_recursive_depth)
  235. new_terms.append(new_term)
  236. else:
  237. new_terms.append(term)
  238. return Add(*new_terms)
  239. def normal_order(expr, recursive_limit=10, _recursive_depth=0):
  240. """Normal order an expression with bosonic or fermionic operators. Note
  241. that this normal order is not equivalent to the original expression, but
  242. the creation and annihilation operators in each term in expr is reordered
  243. so that the expression becomes normal ordered.
  244. Parameters
  245. ==========
  246. expr : expression
  247. The expression to normal order.
  248. recursive_limit : int (default 10)
  249. The number of allowed recursive applications of the function.
  250. Examples
  251. ========
  252. >>> from sympy.physics.quantum import Dagger
  253. >>> from sympy.physics.quantum.boson import BosonOp
  254. >>> from sympy.physics.quantum.operatorordering import normal_order
  255. >>> a = BosonOp("a")
  256. >>> normal_order(a * Dagger(a))
  257. Dagger(a)*a
  258. """
  259. if _recursive_depth > recursive_limit:
  260. warnings.warn("Too many recursions, aborting")
  261. return expr
  262. if isinstance(expr, Add):
  263. return _normal_order_terms(expr, recursive_limit=recursive_limit,
  264. _recursive_depth=_recursive_depth)
  265. elif isinstance(expr, Mul):
  266. return _normal_order_factor(expr, recursive_limit=recursive_limit,
  267. _recursive_depth=_recursive_depth)
  268. else:
  269. return expr