wigner.py 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. # -*- coding: utf-8 -*-
  2. r"""
  3. Wigner, Clebsch-Gordan, Racah, and Gaunt coefficients
  4. Collection of functions for calculating Wigner 3j, 6j, 9j,
  5. Clebsch-Gordan, Racah as well as Gaunt coefficients exactly, all
  6. evaluating to a rational number times the square root of a rational
  7. number [Rasch03]_.
  8. Please see the description of the individual functions for further
  9. details and examples.
  10. References
  11. ==========
  12. .. [Regge58] 'Symmetry Properties of Clebsch-Gordan Coefficients',
  13. T. Regge, Nuovo Cimento, Volume 10, pp. 544 (1958)
  14. .. [Regge59] 'Symmetry Properties of Racah Coefficients',
  15. T. Regge, Nuovo Cimento, Volume 11, pp. 116 (1959)
  16. .. [Edmonds74] A. R. Edmonds. Angular momentum in quantum mechanics.
  17. Investigations in physics, 4.; Investigations in physics, no. 4.
  18. Princeton, N.J., Princeton University Press, 1957.
  19. .. [Rasch03] J. Rasch and A. C. H. Yu, 'Efficient Storage Scheme for
  20. Pre-calculated Wigner 3j, 6j and Gaunt Coefficients', SIAM
  21. J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003)
  22. .. [Liberatodebrito82] 'FORTRAN program for the integral of three
  23. spherical harmonics', A. Liberato de Brito,
  24. Comput. Phys. Commun., Volume 25, pp. 81-85 (1982)
  25. .. [Homeier96] 'Some Properties of the Coupling Coefficients of Real
  26. Spherical Harmonics and Their Relation to Gaunt Coefficients',
  27. H. H. H. Homeier and E. O. Steinborn J. Mol. Struct., Volume 368,
  28. pp. 31-37 (1996)
  29. Credits and Copyright
  30. =====================
  31. This code was taken from Sage with the permission of all authors:
  32. https://groups.google.com/forum/#!topic/sage-devel/M4NZdu-7O38
  33. Authors
  34. =======
  35. - Jens Rasch (2009-03-24): initial version for Sage
  36. - Jens Rasch (2009-05-31): updated to sage-4.0
  37. - Oscar Gerardo Lazo Arjona (2017-06-18): added Wigner D matrices
  38. - Phil Adam LeMaitre (2022-09-19): added real Gaunt coefficient
  39. Copyright (C) 2008 Jens Rasch <jyr2000@gmail.com>
  40. """
  41. from sympy.concrete.summations import Sum
  42. from sympy.core.add import Add
  43. from sympy.core.numbers import int_valued
  44. from sympy.core.function import Function
  45. from sympy.core.numbers import (Float, I, Integer, pi, Rational)
  46. from sympy.core.singleton import S
  47. from sympy.core.symbol import Dummy
  48. from sympy.core.sympify import sympify
  49. from sympy.functions.combinatorial.factorials import (binomial, factorial)
  50. from sympy.functions.elementary.complexes import re
  51. from sympy.functions.elementary.exponential import exp
  52. from sympy.functions.elementary.miscellaneous import sqrt
  53. from sympy.functions.elementary.trigonometric import (cos, sin)
  54. from sympy.functions.special.spherical_harmonics import Ynm
  55. from sympy.matrices.dense import zeros
  56. from sympy.matrices.immutable import ImmutableMatrix
  57. from sympy.utilities.misc import as_int
  58. # This list of precomputed factorials is needed to massively
  59. # accelerate future calculations of the various coefficients
  60. _Factlist = [1]
  61. def _calc_factlist(nn):
  62. r"""
  63. Function calculates a list of precomputed factorials in order to
  64. massively accelerate future calculations of the various
  65. coefficients.
  66. Parameters
  67. ==========
  68. nn : integer
  69. Highest factorial to be computed.
  70. Returns
  71. =======
  72. list of integers :
  73. The list of precomputed factorials.
  74. Examples
  75. ========
  76. Calculate list of factorials::
  77. sage: from sage.functions.wigner import _calc_factlist
  78. sage: _calc_factlist(10)
  79. [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
  80. """
  81. if nn >= len(_Factlist):
  82. for ii in range(len(_Factlist), int(nn + 1)):
  83. _Factlist.append(_Factlist[ii - 1] * ii)
  84. return _Factlist[:int(nn) + 1]
  85. def _int_or_halfint(value):
  86. """return Python int unless value is half-int (then return float)"""
  87. if isinstance(value, int):
  88. return value
  89. elif type(value) is float:
  90. if value.is_integer():
  91. return int(value) # an int
  92. if (2*value).is_integer():
  93. return value # a float
  94. elif isinstance(value, Rational):
  95. if value.q == 2:
  96. return value.p/value.q # a float
  97. elif value.q == 1:
  98. return value.p # an int
  99. elif isinstance(value, Float):
  100. return _int_or_halfint(float(value))
  101. raise ValueError("expecting integer or half-integer, got %s" % value)
  102. def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
  103. r"""
  104. Calculate the Wigner 3j symbol `\operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)`.
  105. Parameters
  106. ==========
  107. j_1, j_2, j_3, m_1, m_2, m_3 :
  108. Integer or half integer.
  109. Returns
  110. =======
  111. Rational number times the square root of a rational number.
  112. Examples
  113. ========
  114. >>> from sympy.physics.wigner import wigner_3j
  115. >>> wigner_3j(2, 6, 4, 0, 0, 0)
  116. sqrt(715)/143
  117. >>> wigner_3j(2, 6, 4, 0, 0, 1)
  118. 0
  119. It is an error to have arguments that are not integer or half
  120. integer values::
  121. sage: wigner_3j(2.1, 6, 4, 0, 0, 0)
  122. Traceback (most recent call last):
  123. ...
  124. ValueError: j values must be integer or half integer
  125. sage: wigner_3j(2, 6, 4, 1, 0, -1.1)
  126. Traceback (most recent call last):
  127. ...
  128. ValueError: m values must be integer or half integer
  129. Notes
  130. =====
  131. The Wigner 3j symbol obeys the following symmetry rules:
  132. - invariant under any permutation of the columns (with the
  133. exception of a sign change where `J:=j_1+j_2+j_3`):
  134. .. math::
  135. \begin{aligned}
  136. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)
  137. &=\operatorname{Wigner3j}(j_3,j_1,j_2,m_3,m_1,m_2) \\
  138. &=\operatorname{Wigner3j}(j_2,j_3,j_1,m_2,m_3,m_1) \\
  139. &=(-1)^J \operatorname{Wigner3j}(j_3,j_2,j_1,m_3,m_2,m_1) \\
  140. &=(-1)^J \operatorname{Wigner3j}(j_1,j_3,j_2,m_1,m_3,m_2) \\
  141. &=(-1)^J \operatorname{Wigner3j}(j_2,j_1,j_3,m_2,m_1,m_3)
  142. \end{aligned}
  143. - invariant under space inflection, i.e.
  144. .. math::
  145. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)
  146. =(-1)^J \operatorname{Wigner3j}(j_1,j_2,j_3,-m_1,-m_2,-m_3)
  147. - symmetric with respect to the 72 additional symmetries based on
  148. the work by [Regge58]_
  149. - zero for `j_1`, `j_2`, `j_3` not fulfilling triangle relation
  150. - zero for `m_1 + m_2 + m_3 \neq 0`
  151. - zero for violating any one of the conditions
  152. `m_1 \in \{-|j_1|, \ldots, |j_1|\}`,
  153. `m_2 \in \{-|j_2|, \ldots, |j_2|\}`,
  154. `m_3 \in \{-|j_3|, \ldots, |j_3|\}`
  155. Algorithm
  156. =========
  157. This function uses the algorithm of [Edmonds74]_ to calculate the
  158. value of the 3j symbol exactly. Note that the formula contains
  159. alternating sums over large factorials and is therefore unsuitable
  160. for finite precision arithmetic and only useful for a computer
  161. algebra system [Rasch03]_.
  162. Authors
  163. =======
  164. - Jens Rasch (2009-03-24): initial version
  165. """
  166. j_1, j_2, j_3, m_1, m_2, m_3 = \
  167. map(_int_or_halfint, map(sympify,
  168. [j_1, j_2, j_3, m_1, m_2, m_3]))
  169. if m_1 + m_2 + m_3 != 0:
  170. return S.Zero
  171. a1 = j_1 + j_2 - j_3
  172. if a1 < 0:
  173. return S.Zero
  174. a2 = j_1 - j_2 + j_3
  175. if a2 < 0:
  176. return S.Zero
  177. a3 = -j_1 + j_2 + j_3
  178. if a3 < 0:
  179. return S.Zero
  180. if (abs(m_1) > j_1) or (abs(m_2) > j_2) or (abs(m_3) > j_3):
  181. return S.Zero
  182. if not (int_valued(j_1 - m_1) and \
  183. int_valued(j_2 - m_2) and \
  184. int_valued(j_3 - m_3)):
  185. return S.Zero
  186. maxfact = max(j_1 + j_2 + j_3 + 1, j_1 + abs(m_1), j_2 + abs(m_2),
  187. j_3 + abs(m_3))
  188. _calc_factlist(int(maxfact))
  189. argsqrt = Integer(_Factlist[int(j_1 + j_2 - j_3)] *
  190. _Factlist[int(j_1 - j_2 + j_3)] *
  191. _Factlist[int(-j_1 + j_2 + j_3)] *
  192. _Factlist[int(j_1 - m_1)] *
  193. _Factlist[int(j_1 + m_1)] *
  194. _Factlist[int(j_2 - m_2)] *
  195. _Factlist[int(j_2 + m_2)] *
  196. _Factlist[int(j_3 - m_3)] *
  197. _Factlist[int(j_3 + m_3)]) / \
  198. _Factlist[int(j_1 + j_2 + j_3 + 1)]
  199. ressqrt = sqrt(argsqrt)
  200. if ressqrt.is_complex or ressqrt.is_infinite:
  201. ressqrt = ressqrt.as_real_imag()[0]
  202. imin = max(-j_3 + j_1 + m_2, -j_3 + j_2 - m_1, 0)
  203. imax = min(j_2 + m_2, j_1 - m_1, j_1 + j_2 - j_3)
  204. sumres = 0
  205. for ii in range(int(imin), int(imax) + 1):
  206. den = _Factlist[ii] * \
  207. _Factlist[int(ii + j_3 - j_1 - m_2)] * \
  208. _Factlist[int(j_2 + m_2 - ii)] * \
  209. _Factlist[int(j_1 - ii - m_1)] * \
  210. _Factlist[int(ii + j_3 - j_2 + m_1)] * \
  211. _Factlist[int(j_1 + j_2 - j_3 - ii)]
  212. sumres = sumres + Integer((-1) ** ii) / den
  213. prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
  214. res = ressqrt * sumres * prefid
  215. return res
  216. def clebsch_gordan(j_1, j_2, j_3, m_1, m_2, m_3):
  217. r"""
  218. Calculates the Clebsch-Gordan coefficient.
  219. `\left\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \right\rangle`.
  220. The reference for this function is [Edmonds74]_.
  221. Parameters
  222. ==========
  223. j_1, j_2, j_3, m_1, m_2, m_3 :
  224. Integer or half integer.
  225. Returns
  226. =======
  227. Rational number times the square root of a rational number.
  228. Examples
  229. ========
  230. >>> from sympy import S
  231. >>> from sympy.physics.wigner import clebsch_gordan
  232. >>> clebsch_gordan(S(3)/2, S(1)/2, 2, S(3)/2, S(1)/2, 2)
  233. 1
  234. >>> clebsch_gordan(S(3)/2, S(1)/2, 1, S(3)/2, -S(1)/2, 1)
  235. sqrt(3)/2
  236. >>> clebsch_gordan(S(3)/2, S(1)/2, 1, -S(1)/2, S(1)/2, 0)
  237. -sqrt(2)/2
  238. Notes
  239. =====
  240. The Clebsch-Gordan coefficient will be evaluated via its relation
  241. to Wigner 3j symbols:
  242. .. math::
  243. \left\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \right\rangle
  244. =(-1)^{j_1-j_2+m_3} \sqrt{2j_3+1}
  245. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,-m_3)
  246. See also the documentation on Wigner 3j symbols which exhibit much
  247. higher symmetry relations than the Clebsch-Gordan coefficient.
  248. Authors
  249. =======
  250. - Jens Rasch (2009-03-24): initial version
  251. """
  252. j_1 = sympify(j_1)
  253. j_2 = sympify(j_2)
  254. j_3 = sympify(j_3)
  255. m_1 = sympify(m_1)
  256. m_2 = sympify(m_2)
  257. m_3 = sympify(m_3)
  258. w = wigner_3j(j_1, j_2, j_3, m_1, m_2, -m_3)
  259. return (-1) ** (j_1 - j_2 + m_3) * sqrt(2 * j_3 + 1) * w
  260. def _big_delta_coeff(aa, bb, cc, prec=None):
  261. r"""
  262. Calculates the Delta coefficient of the 3 angular momenta for
  263. Racah symbols. Also checks that the differences are of integer
  264. value.
  265. Parameters
  266. ==========
  267. aa :
  268. First angular momentum, integer or half integer.
  269. bb :
  270. Second angular momentum, integer or half integer.
  271. cc :
  272. Third angular momentum, integer or half integer.
  273. prec :
  274. Precision of the ``sqrt()`` calculation.
  275. Returns
  276. =======
  277. double : Value of the Delta coefficient.
  278. Examples
  279. ========
  280. sage: from sage.functions.wigner import _big_delta_coeff
  281. sage: _big_delta_coeff(1,1,1)
  282. 1/2*sqrt(1/6)
  283. """
  284. # the triangle test will only pass if a) all 3 values are ints or
  285. # b) 1 is an int and the other two are half-ints
  286. if not int_valued(aa + bb - cc):
  287. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  288. if not int_valued(aa + cc - bb):
  289. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  290. if not int_valued(bb + cc - aa):
  291. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  292. if (aa + bb - cc) < 0:
  293. return S.Zero
  294. if (aa + cc - bb) < 0:
  295. return S.Zero
  296. if (bb + cc - aa) < 0:
  297. return S.Zero
  298. maxfact = max(aa + bb - cc, aa + cc - bb, bb + cc - aa, aa + bb + cc + 1)
  299. _calc_factlist(maxfact)
  300. argsqrt = Integer(_Factlist[int(aa + bb - cc)] *
  301. _Factlist[int(aa + cc - bb)] *
  302. _Factlist[int(bb + cc - aa)]) / \
  303. Integer(_Factlist[int(aa + bb + cc + 1)])
  304. ressqrt = sqrt(argsqrt)
  305. if prec:
  306. ressqrt = ressqrt.evalf(prec).as_real_imag()[0]
  307. return ressqrt
  308. def racah(aa, bb, cc, dd, ee, ff, prec=None):
  309. r"""
  310. Calculate the Racah symbol `W(a,b,c,d;e,f)`.
  311. Parameters
  312. ==========
  313. a, ..., f :
  314. Integer or half integer.
  315. prec :
  316. Precision, default: ``None``. Providing a precision can
  317. drastically speed up the calculation.
  318. Returns
  319. =======
  320. Rational number times the square root of a rational number
  321. (if ``prec=None``), or real number if a precision is given.
  322. Examples
  323. ========
  324. >>> from sympy.physics.wigner import racah
  325. >>> racah(3,3,3,3,3,3)
  326. -1/14
  327. Notes
  328. =====
  329. The Racah symbol is related to the Wigner 6j symbol:
  330. .. math::
  331. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  332. =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
  333. Please see the 6j symbol for its much richer symmetries and for
  334. additional properties.
  335. Algorithm
  336. =========
  337. This function uses the algorithm of [Edmonds74]_ to calculate the
  338. value of the 6j symbol exactly. Note that the formula contains
  339. alternating sums over large factorials and is therefore unsuitable
  340. for finite precision arithmetic and only useful for a computer
  341. algebra system [Rasch03]_.
  342. Authors
  343. =======
  344. - Jens Rasch (2009-03-24): initial version
  345. """
  346. prefac = _big_delta_coeff(aa, bb, ee, prec) * \
  347. _big_delta_coeff(cc, dd, ee, prec) * \
  348. _big_delta_coeff(aa, cc, ff, prec) * \
  349. _big_delta_coeff(bb, dd, ff, prec)
  350. if prefac == 0:
  351. return S.Zero
  352. imin = max(aa + bb + ee, cc + dd + ee, aa + cc + ff, bb + dd + ff)
  353. imax = min(aa + bb + cc + dd, aa + dd + ee + ff, bb + cc + ee + ff)
  354. maxfact = max(imax + 1, aa + bb + cc + dd, aa + dd + ee + ff,
  355. bb + cc + ee + ff)
  356. _calc_factlist(maxfact)
  357. sumres = 0
  358. for kk in range(int(imin), int(imax) + 1):
  359. den = _Factlist[int(kk - aa - bb - ee)] * \
  360. _Factlist[int(kk - cc - dd - ee)] * \
  361. _Factlist[int(kk - aa - cc - ff)] * \
  362. _Factlist[int(kk - bb - dd - ff)] * \
  363. _Factlist[int(aa + bb + cc + dd - kk)] * \
  364. _Factlist[int(aa + dd + ee + ff - kk)] * \
  365. _Factlist[int(bb + cc + ee + ff - kk)]
  366. sumres = sumres + Integer((-1) ** kk * _Factlist[kk + 1]) / den
  367. res = prefac * sumres * (-1) ** int(aa + bb + cc + dd)
  368. return res
  369. def wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None):
  370. r"""
  371. Calculate the Wigner 6j symbol `\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)`.
  372. Parameters
  373. ==========
  374. j_1, ..., j_6 :
  375. Integer or half integer.
  376. prec :
  377. Precision, default: ``None``. Providing a precision can
  378. drastically speed up the calculation.
  379. Returns
  380. =======
  381. Rational number times the square root of a rational number
  382. (if ``prec=None``), or real number if a precision is given.
  383. Examples
  384. ========
  385. >>> from sympy.physics.wigner import wigner_6j
  386. >>> wigner_6j(3,3,3,3,3,3)
  387. -1/14
  388. >>> wigner_6j(5,5,5,5,5,5)
  389. 1/52
  390. It is an error to have arguments that are not integer or half
  391. integer values or do not fulfill the triangle relation::
  392. sage: wigner_6j(2.5,2.5,2.5,2.5,2.5,2.5)
  393. Traceback (most recent call last):
  394. ...
  395. ValueError: j values must be integer or half integer and fulfill the triangle relation
  396. sage: wigner_6j(0.5,0.5,1.1,0.5,0.5,1.1)
  397. Traceback (most recent call last):
  398. ...
  399. ValueError: j values must be integer or half integer and fulfill the triangle relation
  400. Notes
  401. =====
  402. The Wigner 6j symbol is related to the Racah symbol but exhibits
  403. more symmetries as detailed below.
  404. .. math::
  405. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  406. =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
  407. The Wigner 6j symbol obeys the following symmetry rules:
  408. - Wigner 6j symbols are left invariant under any permutation of
  409. the columns:
  410. .. math::
  411. \begin{aligned}
  412. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  413. &=\operatorname{Wigner6j}(j_3,j_1,j_2,j_6,j_4,j_5) \\
  414. &=\operatorname{Wigner6j}(j_2,j_3,j_1,j_5,j_6,j_4) \\
  415. &=\operatorname{Wigner6j}(j_3,j_2,j_1,j_6,j_5,j_4) \\
  416. &=\operatorname{Wigner6j}(j_1,j_3,j_2,j_4,j_6,j_5) \\
  417. &=\operatorname{Wigner6j}(j_2,j_1,j_3,j_5,j_4,j_6)
  418. \end{aligned}
  419. - They are invariant under the exchange of the upper and lower
  420. arguments in each of any two columns, i.e.
  421. .. math::
  422. \begin{aligned}
  423. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  424. &=\operatorname{Wigner6j}(j_1,j_5,j_6,j_4,j_2,j_3)\\
  425. &=\operatorname{Wigner6j}(j_4,j_2,j_6,j_1,j_5,j_3)\\
  426. &=\operatorname{Wigner6j}(j_4,j_5,j_3,j_1,j_2,j_6)
  427. \end{aligned}
  428. - additional 6 symmetries [Regge59]_ giving rise to 144 symmetries
  429. in total
  430. - only non-zero if any triple of `j`'s fulfill a triangle relation
  431. Algorithm
  432. =========
  433. This function uses the algorithm of [Edmonds74]_ to calculate the
  434. value of the 6j symbol exactly. Note that the formula contains
  435. alternating sums over large factorials and is therefore unsuitable
  436. for finite precision arithmetic and only useful for a computer
  437. algebra system [Rasch03]_.
  438. """
  439. j_1, j_2, j_3, j_4, j_5, j_6 = map(sympify, \
  440. [j_1, j_2, j_3, j_4, j_5, j_6])
  441. res = (-1) ** int(j_1 + j_2 + j_4 + j_5) * \
  442. racah(j_1, j_2, j_5, j_4, j_3, j_6, prec)
  443. return res
  444. def wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None):
  445. r"""
  446. Calculate the Wigner 9j symbol
  447. `\operatorname{Wigner9j}(j_1,j_2,j_3,j_4,j_5,j_6,j_7,j_8,j_9)`.
  448. Parameters
  449. ==========
  450. j_1, ..., j_9 :
  451. Integer or half integer.
  452. prec : precision, default
  453. ``None``. Providing a precision can
  454. drastically speed up the calculation.
  455. Returns
  456. =======
  457. Rational number times the square root of a rational number
  458. (if ``prec=None``), or real number if a precision is given.
  459. Examples
  460. ========
  461. >>> from sympy.physics.wigner import wigner_9j
  462. >>> wigner_9j(1,1,1, 1,1,1, 1,1,0, prec=64)
  463. 0.05555555555555555555555555555555555555555555555555555555555555555
  464. >>> wigner_9j(1/2,1/2,0, 1/2,3/2,1, 0,1,1, prec=64)
  465. 0.1666666666666666666666666666666666666666666666666666666666666667
  466. It is an error to have arguments that are not integer or half
  467. integer values or do not fulfill the triangle relation::
  468. sage: wigner_9j(0.5,0.5,0.5, 0.5,0.5,0.5, 0.5,0.5,0.5,prec=64)
  469. Traceback (most recent call last):
  470. ...
  471. ValueError: j values must be integer or half integer and fulfill the triangle relation
  472. sage: wigner_9j(1,1,1, 0.5,1,1.5, 0.5,1,2.5,prec=64)
  473. Traceback (most recent call last):
  474. ...
  475. ValueError: j values must be integer or half integer and fulfill the triangle relation
  476. Algorithm
  477. =========
  478. This function uses the algorithm of [Edmonds74]_ to calculate the
  479. value of the 3j symbol exactly. Note that the formula contains
  480. alternating sums over large factorials and is therefore unsuitable
  481. for finite precision arithmetic and only useful for a computer
  482. algebra system [Rasch03]_.
  483. """
  484. j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9 = map(sympify, \
  485. [j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9])
  486. imax = int(min(j_1 + j_9, j_2 + j_6, j_4 + j_8) * 2)
  487. imin = imax % 2
  488. sumres = 0
  489. for kk in range(imin, int(imax) + 1, 2):
  490. sumres = sumres + (kk + 1) * \
  491. racah(j_1, j_2, j_9, j_6, j_3, kk / 2, prec) * \
  492. racah(j_4, j_6, j_8, j_2, j_5, kk / 2, prec) * \
  493. racah(j_1, j_4, j_9, j_8, j_7, kk / 2, prec)
  494. return sumres
  495. def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None):
  496. r"""
  497. Calculate the Gaunt coefficient.
  498. Explanation
  499. ===========
  500. The Gaunt coefficient is defined as the integral over three
  501. spherical harmonics:
  502. .. math::
  503. \begin{aligned}
  504. \operatorname{Gaunt}(l_1,l_2,l_3,m_1,m_2,m_3)
  505. &=\int Y_{l_1,m_1}(\Omega)
  506. Y_{l_2,m_2}(\Omega) Y_{l_3,m_3}(\Omega) \,d\Omega \\
  507. &=\sqrt{\frac{(2l_1+1)(2l_2+1)(2l_3+1)}{4\pi}}
  508. \operatorname{Wigner3j}(l_1,l_2,l_3,0,0,0)
  509. \operatorname{Wigner3j}(l_1,l_2,l_3,m_1,m_2,m_3)
  510. \end{aligned}
  511. Parameters
  512. ==========
  513. l_1, l_2, l_3, m_1, m_2, m_3 :
  514. Integer.
  515. prec - precision, default: ``None``.
  516. Providing a precision can
  517. drastically speed up the calculation.
  518. Returns
  519. =======
  520. Rational number times the square root of a rational number
  521. (if ``prec=None``), or real number if a precision is given.
  522. Examples
  523. ========
  524. >>> from sympy.physics.wigner import gaunt
  525. >>> gaunt(1,0,1,1,0,-1)
  526. -1/(2*sqrt(pi))
  527. >>> gaunt(1000,1000,1200,9,3,-12).n(64)
  528. 0.006895004219221134484332976156744208248842039317638217822322799675
  529. It is an error to use non-integer values for `l` and `m`::
  530. sage: gaunt(1.2,0,1.2,0,0,0)
  531. Traceback (most recent call last):
  532. ...
  533. ValueError: l values must be integer
  534. sage: gaunt(1,0,1,1.1,0,-1.1)
  535. Traceback (most recent call last):
  536. ...
  537. ValueError: m values must be integer
  538. Notes
  539. =====
  540. The Gaunt coefficient obeys the following symmetry rules:
  541. - invariant under any permutation of the columns
  542. .. math::
  543. \begin{aligned}
  544. Y(l_1,l_2,l_3,m_1,m_2,m_3)
  545. &=Y(l_3,l_1,l_2,m_3,m_1,m_2) \\
  546. &=Y(l_2,l_3,l_1,m_2,m_3,m_1) \\
  547. &=Y(l_3,l_2,l_1,m_3,m_2,m_1) \\
  548. &=Y(l_1,l_3,l_2,m_1,m_3,m_2) \\
  549. &=Y(l_2,l_1,l_3,m_2,m_1,m_3)
  550. \end{aligned}
  551. - invariant under space inflection, i.e.
  552. .. math::
  553. Y(l_1,l_2,l_3,m_1,m_2,m_3)
  554. =Y(l_1,l_2,l_3,-m_1,-m_2,-m_3)
  555. - symmetric with respect to the 72 Regge symmetries as inherited
  556. for the `3j` symbols [Regge58]_
  557. - zero for `l_1`, `l_2`, `l_3` not fulfilling triangle relation
  558. - zero for violating any one of the conditions: `l_1 \ge |m_1|`,
  559. `l_2 \ge |m_2|`, `l_3 \ge |m_3|`
  560. - non-zero only for an even sum of the `l_i`, i.e.
  561. `L = l_1 + l_2 + l_3 = 2n` for `n` in `\mathbb{N}`
  562. Algorithms
  563. ==========
  564. This function uses the algorithm of [Liberatodebrito82]_ to
  565. calculate the value of the Gaunt coefficient exactly. Note that
  566. the formula contains alternating sums over large factorials and is
  567. therefore unsuitable for finite precision arithmetic and only
  568. useful for a computer algebra system [Rasch03]_.
  569. Authors
  570. =======
  571. Jens Rasch (2009-03-24): initial version for Sage.
  572. """
  573. l_1, l_2, l_3, m_1, m_2, m_3 = [
  574. as_int(i) for i in (l_1, l_2, l_3, m_1, m_2, m_3)]
  575. if l_1 + l_2 - l_3 < 0:
  576. return S.Zero
  577. if l_1 - l_2 + l_3 < 0:
  578. return S.Zero
  579. if -l_1 + l_2 + l_3 < 0:
  580. return S.Zero
  581. if (m_1 + m_2 + m_3) != 0:
  582. return S.Zero
  583. if (abs(m_1) > l_1) or (abs(m_2) > l_2) or (abs(m_3) > l_3):
  584. return S.Zero
  585. bigL, remL = divmod(l_1 + l_2 + l_3, 2)
  586. if remL % 2:
  587. return S.Zero
  588. imin = max(-l_3 + l_1 + m_2, -l_3 + l_2 - m_1, 0)
  589. imax = min(l_2 + m_2, l_1 - m_1, l_1 + l_2 - l_3)
  590. _calc_factlist(max(l_1 + l_2 + l_3 + 1, imax + 1))
  591. ressqrt = sqrt((2 * l_1 + 1) * (2 * l_2 + 1) * (2 * l_3 + 1) * \
  592. _Factlist[l_1 - m_1] * _Factlist[l_1 + m_1] * _Factlist[l_2 - m_2] * \
  593. _Factlist[l_2 + m_2] * _Factlist[l_3 - m_3] * _Factlist[l_3 + m_3] / \
  594. (4*pi))
  595. prefac = Integer(_Factlist[bigL] * _Factlist[l_2 - l_1 + l_3] *
  596. _Factlist[l_1 - l_2 + l_3] * _Factlist[l_1 + l_2 - l_3])/ \
  597. _Factlist[2 * bigL + 1]/ \
  598. (_Factlist[bigL - l_1] *
  599. _Factlist[bigL - l_2] * _Factlist[bigL - l_3])
  600. sumres = 0
  601. for ii in range(int(imin), int(imax) + 1):
  602. den = _Factlist[ii] * _Factlist[ii + l_3 - l_1 - m_2] * \
  603. _Factlist[l_2 + m_2 - ii] * _Factlist[l_1 - ii - m_1] * \
  604. _Factlist[ii + l_3 - l_2 + m_1] * _Factlist[l_1 + l_2 - l_3 - ii]
  605. sumres = sumres + Integer((-1) ** ii) / den
  606. res = ressqrt * prefac * sumres * Integer((-1) ** (bigL + l_3 + m_1 - m_2))
  607. if prec is not None:
  608. res = res.n(prec)
  609. return res
  610. def real_gaunt(l_1, l_2, l_3, mu_1, mu_2, mu_3, prec=None):
  611. r"""
  612. Calculate the real Gaunt coefficient.
  613. Explanation
  614. ===========
  615. The real Gaunt coefficient is defined as the integral over three
  616. real spherical harmonics:
  617. .. math::
  618. \begin{aligned}
  619. \operatorname{RealGaunt}(l_1,l_2,l_3,\mu_1,\mu_2,\mu_3)
  620. &=\int Z^{\mu_1}_{l_1}(\Omega)
  621. Z^{\mu_2}_{l_2}(\Omega) Z^{\mu_3}_{l_3}(\Omega) \,d\Omega \\
  622. \end{aligned}
  623. Alternatively, it can be defined in terms of the standard Gaunt
  624. coefficient by relating the real spherical harmonics to the standard
  625. spherical harmonics via a unitary transformation `U`, i.e.
  626. `Z^{\mu}_{l}(\Omega)=\sum_{m'}U^{\mu}_{m'}Y^{m'}_{l}(\Omega)` [Homeier96]_.
  627. The real Gaunt coefficient is then defined as
  628. .. math::
  629. \begin{aligned}
  630. \operatorname{RealGaunt}(l_1,l_2,l_3,\mu_1,\mu_2,\mu_3)
  631. &=\int Z^{\mu_1}_{l_1}(\Omega)
  632. Z^{\mu_2}_{l_2}(\Omega) Z^{\mu_3}_{l_3}(\Omega) \,d\Omega \\
  633. &=\sum_{m'_1 m'_2 m'_3} U^{\mu_1}_{m'_1}U^{\mu_2}_{m'_2}U^{\mu_3}_{m'_3}
  634. \operatorname{Gaunt}(l_1,l_2,l_3,m'_1,m'_2,m'_3)
  635. \end{aligned}
  636. The unitary matrix `U` has components
  637. .. math::
  638. \begin{aligned}
  639. U^\mu_{m} = \delta_{|\mu||m|}*(\delta_{m0}\delta_{\mu 0} + \frac{1}{\sqrt{2}}\big[\Theta(\mu)\big(\delta_{m\mu}+(-1)^{m}\delta_{m-\mu}\big)
  640. +i \Theta(-\mu)\big((-1)^{m}\delta_{m\mu}-\delta_{m-\mu}\big)\big])
  641. \end{aligned}
  642. where `\delta_{ij}` is the Kronecker delta symbol and `\Theta` is a step
  643. function defined as
  644. .. math::
  645. \begin{aligned}
  646. \Theta(x) = \begin{cases} 1 \,\text{for}\, x > 0 \\ 0 \,\text{for}\, x \leq 0 \end{cases}
  647. \end{aligned}
  648. Parameters
  649. ==========
  650. l_1, l_2, l_3, mu_1, mu_2, mu_3 :
  651. Integer degree and order
  652. prec - precision, default: ``None``.
  653. Providing a precision can
  654. drastically speed up the calculation.
  655. Returns
  656. =======
  657. Rational number times the square root of a rational number.
  658. Examples
  659. ========
  660. >>> from sympy.physics.wigner import real_gaunt
  661. >>> real_gaunt(1,1,2,-1,1,-2)
  662. sqrt(15)/(10*sqrt(pi))
  663. >>> real_gaunt(10,10,20,-9,-9,0,prec=64)
  664. -0.00002480019791932209313156167176797577821140084216297395518482071448
  665. It is an error to use non-integer values for `l` and `\mu`::
  666. real_gaunt(2.8,0.5,1.3,0,0,0)
  667. Traceback (most recent call last):
  668. ...
  669. ValueError: l values must be integer
  670. real_gaunt(2,2,4,0.7,1,-3.4)
  671. Traceback (most recent call last):
  672. ...
  673. ValueError: mu values must be integer
  674. Notes
  675. =====
  676. The real Gaunt coefficient inherits from the standard Gaunt coefficient,
  677. the invariance under any permutation of the pairs `(l_i, \mu_i)` and the
  678. requirement that the sum of the `l_i` be even to yield a non-zero value.
  679. It also obeys the following symmetry rules:
  680. - zero for `l_1`, `l_2`, `l_3` not fulfilling the condition
  681. `l_1 \in \{l_{\text{max}}, l_{\text{max}}-2, \ldots, l_{\text{min}}\}`,
  682. where `l_{\text{max}} = l_2+l_3`,
  683. .. math::
  684. \begin{aligned}
  685. l_{\text{min}} = \begin{cases} \kappa(l_2, l_3, \mu_2, \mu_3) & \text{if}\,
  686. \kappa(l_2, l_3, \mu_2, \mu_3) + l_{\text{max}}\, \text{is even} \\
  687. \kappa(l_2, l_3, \mu_2, \mu_3)+1 & \text{if}\, \kappa(l_2, l_3, \mu_2, \mu_3) +
  688. l_{\text{max}}\, \text{is odd}\end{cases}
  689. \end{aligned}
  690. and `\kappa(l_2, l_3, \mu_2, \mu_3) = \max{\big(|l_2-l_3|, \min{\big(|\mu_2+\mu_3|,
  691. |\mu_2-\mu_3|\big)}\big)}`
  692. - zero for an odd number of negative `\mu_i`
  693. Algorithms
  694. ==========
  695. This function uses the algorithms of [Homeier96]_ and [Rasch03]_ to
  696. calculate the value of the real Gaunt coefficient exactly. Note that
  697. the formula used in [Rasch03]_ contains alternating sums over large
  698. factorials and is therefore unsuitable for finite precision arithmetic
  699. and only useful for a computer algebra system [Rasch03]_. However, this
  700. function can in principle use any algorithm that computes the Gaunt
  701. coefficient, so it is suitable for finite precision arithmetic in so far
  702. as the algorithm which computes the Gaunt coefficient is.
  703. """
  704. l_1, l_2, l_3, mu_1, mu_2, mu_3 = [
  705. as_int(i) for i in (l_1, l_2, l_3, mu_1, mu_2, mu_3)]
  706. # check for quick exits
  707. if sum(1 for i in (mu_1, mu_2, mu_3) if i < 0) % 2:
  708. return S.Zero # odd number of negative m
  709. if (l_1 + l_2 + l_3) % 2:
  710. return S.Zero # sum of l is odd
  711. lmax = l_2 + l_3
  712. lmin = max(abs(l_2 - l_3), min(abs(mu_2 + mu_3), abs(mu_2 - mu_3)))
  713. if (lmin + lmax) % 2:
  714. lmin += 1
  715. if lmin not in range(lmax, lmin - 2, -2):
  716. return S.Zero
  717. kron_del = lambda i, j: 1 if i == j else 0
  718. s = lambda e: -1 if e % 2 else 1 # (-1)**e to give +/-1, avoiding float when e<0
  719. t = lambda x: 1 if x > 0 else 0
  720. A = lambda mu, m: t(-mu) * (s(m) * kron_del(m, mu) - kron_del(m, -mu))
  721. B = lambda mu, m: t(mu) * (kron_del(m, mu) + s(m) * kron_del(m, -mu))
  722. U = lambda mu, m: kron_del(abs(mu), abs(m)) * (kron_del(mu, 0) * kron_del(m, 0) + (B(mu, m) + I * A(mu, m))/sqrt(2))
  723. ugnt = 0
  724. for m1 in range(-l_1, l_1+1):
  725. U1 = U(mu_1, m1)
  726. for m2 in range(-l_2, l_2+1):
  727. U2 = U(mu_2, m2)
  728. U3 = U(mu_3,-m1-m2)
  729. ugnt = ugnt + re(U1*U2*U3)*gaunt(l_1, l_2, l_3, m1, m2, -m1 - m2, prec=prec)
  730. return ugnt
  731. class Wigner3j(Function):
  732. def doit(self, **hints):
  733. if all(obj.is_number for obj in self.args):
  734. return wigner_3j(*self.args)
  735. else:
  736. return self
  737. def dot_rot_grad_Ynm(j, p, l, m, theta, phi):
  738. r"""
  739. Returns dot product of rotational gradients of spherical harmonics.
  740. Explanation
  741. ===========
  742. This function returns the right hand side of the following expression:
  743. .. math ::
  744. \vec{R}Y{_j^{p}} \cdot \vec{R}Y{_l^{m}} = (-1)^{m+p}
  745. \sum\limits_{k=|l-j|}^{l+j}Y{_k^{m+p}} * \alpha_{l,m,j,p,k} *
  746. \frac{1}{2} (k^2-j^2-l^2+k-j-l)
  747. Arguments
  748. =========
  749. j, p, l, m .... indices in spherical harmonics (expressions or integers)
  750. theta, phi .... angle arguments in spherical harmonics
  751. Example
  752. =======
  753. >>> from sympy import symbols
  754. >>> from sympy.physics.wigner import dot_rot_grad_Ynm
  755. >>> theta, phi = symbols("theta phi")
  756. >>> dot_rot_grad_Ynm(3, 2, 2, 0, theta, phi).doit()
  757. 3*sqrt(55)*Ynm(5, 2, theta, phi)/(11*sqrt(pi))
  758. """
  759. j = sympify(j)
  760. p = sympify(p)
  761. l = sympify(l)
  762. m = sympify(m)
  763. theta = sympify(theta)
  764. phi = sympify(phi)
  765. k = Dummy("k")
  766. def alpha(l,m,j,p,k):
  767. return sqrt((2*l+1)*(2*j+1)*(2*k+1)/(4*pi)) * \
  768. Wigner3j(j, l, k, S.Zero, S.Zero, S.Zero) * \
  769. Wigner3j(j, l, k, p, m, -m-p)
  770. return (S.NegativeOne)**(m+p) * Sum(Ynm(k, m+p, theta, phi) * alpha(l,m,j,p,k) / 2 \
  771. *(k**2-j**2-l**2+k-j-l), (k, abs(l-j), l+j))
  772. def wigner_d_small(J, beta):
  773. """Return the small Wigner d matrix for angular momentum J.
  774. Explanation
  775. ===========
  776. J : An integer, half-integer, or SymPy symbol for the total angular
  777. momentum of the angular momentum space being rotated.
  778. beta : A real number representing the Euler angle of rotation about
  779. the so-called line of nodes. See [Edmonds74]_.
  780. Returns
  781. =======
  782. A matrix representing the corresponding Euler angle rotation( in the basis
  783. of eigenvectors of `J_z`).
  784. .. math ::
  785. \\mathcal{d}_{\\beta} = \\exp\\big( \\frac{i\\beta}{\\hbar} J_y\\big)
  786. such that
  787. .. math ::
  788. d^{(J)}_{m',m}(\\beta) = \\mathtt{wigner\\_d\\_small(J,beta)[J-mprime,J-m]}
  789. The components are calculated using the general form [Edmonds74]_,
  790. equation 4.1.15.
  791. Examples
  792. ========
  793. >>> from sympy import Integer, symbols, pi, pprint
  794. >>> from sympy.physics.wigner import wigner_d_small
  795. >>> half = 1/Integer(2)
  796. >>> beta = symbols("beta", real=True)
  797. >>> pprint(wigner_d_small(half, beta), use_unicode=True)
  798. ⎡ ⎛β⎞ ⎛β⎞⎤
  799. ⎢cos⎜─⎟ sin⎜─⎟⎥
  800. ⎢ ⎝2⎠ ⎝2⎠⎥
  801. ⎢ ⎥
  802. ⎢ ⎛β⎞ ⎛β⎞⎥
  803. ⎢-sin⎜─⎟ cos⎜─⎟⎥
  804. ⎣ ⎝2⎠ ⎝2⎠⎦
  805. >>> pprint(wigner_d_small(2*half, beta), use_unicode=True)
  806. ⎡ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎤
  807. ⎢ cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟ sin ⎜─⎟ ⎥
  808. ⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎥
  809. ⎢ ⎥
  810. ⎢ ⎛β⎞ ⎛β⎞ 2⎛β⎞ 2⎛β⎞ ⎛β⎞ ⎛β⎞⎥
  811. ⎢-√2⋅sin⎜─⎟⋅cos⎜─⎟ - sin ⎜─⎟ + cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟⎥
  812. ⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠⎥
  813. ⎢ ⎥
  814. ⎢ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎥
  815. ⎢ sin ⎜─⎟ -√2⋅sin⎜─⎟⋅cos⎜─⎟ cos ⎜─⎟ ⎥
  816. ⎣ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎦
  817. From table 4 in [Edmonds74]_
  818. >>> pprint(wigner_d_small(half, beta).subs({beta:pi/2}), use_unicode=True)
  819. ⎡ √2 √2⎤
  820. ⎢ ── ──⎥
  821. ⎢ 2 2 ⎥
  822. ⎢ ⎥
  823. ⎢-√2 √2⎥
  824. ⎢──── ──⎥
  825. ⎣ 2 2 ⎦
  826. >>> pprint(wigner_d_small(2*half, beta).subs({beta:pi/2}),
  827. ... use_unicode=True)
  828. ⎡ √2 ⎤
  829. ⎢1/2 ── 1/2⎥
  830. ⎢ 2 ⎥
  831. ⎢ ⎥
  832. ⎢-√2 √2 ⎥
  833. ⎢──── 0 ── ⎥
  834. ⎢ 2 2 ⎥
  835. ⎢ ⎥
  836. ⎢ -√2 ⎥
  837. ⎢1/2 ──── 1/2⎥
  838. ⎣ 2 ⎦
  839. >>> pprint(wigner_d_small(3*half, beta).subs({beta:pi/2}),
  840. ... use_unicode=True)
  841. ⎡ √2 √6 √6 √2⎤
  842. ⎢ ── ── ── ──⎥
  843. ⎢ 4 4 4 4 ⎥
  844. ⎢ ⎥
  845. ⎢-√6 -√2 √2 √6⎥
  846. ⎢──── ──── ── ──⎥
  847. ⎢ 4 4 4 4 ⎥
  848. ⎢ ⎥
  849. ⎢ √6 -√2 -√2 √6⎥
  850. ⎢ ── ──── ──── ──⎥
  851. ⎢ 4 4 4 4 ⎥
  852. ⎢ ⎥
  853. ⎢-√2 √6 -√6 √2⎥
  854. ⎢──── ── ──── ──⎥
  855. ⎣ 4 4 4 4 ⎦
  856. >>> pprint(wigner_d_small(4*half, beta).subs({beta:pi/2}),
  857. ... use_unicode=True)
  858. ⎡ √6 ⎤
  859. ⎢1/4 1/2 ── 1/2 1/4⎥
  860. ⎢ 4 ⎥
  861. ⎢ ⎥
  862. ⎢-1/2 -1/2 0 1/2 1/2⎥
  863. ⎢ ⎥
  864. ⎢ √6 √6 ⎥
  865. ⎢ ── 0 -1/2 0 ── ⎥
  866. ⎢ 4 4 ⎥
  867. ⎢ ⎥
  868. ⎢-1/2 1/2 0 -1/2 1/2⎥
  869. ⎢ ⎥
  870. ⎢ √6 ⎥
  871. ⎢1/4 -1/2 ── -1/2 1/4⎥
  872. ⎣ 4 ⎦
  873. """
  874. M = [J-i for i in range(2*J+1)]
  875. d = zeros(2*J+1)
  876. # Mi corresponds to Edmonds' $m'$, and Mj to $m$.
  877. for i, Mi in enumerate(M):
  878. for j, Mj in enumerate(M):
  879. # We get the maximum and minimum value of sigma.
  880. sigmamax = min([J-Mi, J-Mj])
  881. sigmamin = max([0, -Mi-Mj])
  882. dij = sqrt(factorial(J+Mi)*factorial(J-Mi) /
  883. factorial(J+Mj)/factorial(J-Mj))
  884. terms = [(-1)**(J-Mi-s) *
  885. binomial(J+Mj, J-Mi-s) *
  886. binomial(J-Mj, s) *
  887. cos(beta/2)**(2*s+Mi+Mj) *
  888. sin(beta/2)**(2*J-2*s-Mj-Mi)
  889. for s in range(sigmamin, sigmamax+1)]
  890. d[i, j] = dij*Add(*terms)
  891. return ImmutableMatrix(d)
  892. def wigner_d(J, alpha, beta, gamma):
  893. """Return the Wigner D matrix for angular momentum J.
  894. Explanation
  895. ===========
  896. J :
  897. An integer, half-integer, or SymPy symbol for the total angular
  898. momentum of the angular momentum space being rotated.
  899. alpha, beta, gamma - Real numbers representing the Euler.
  900. Angles of rotation about the so-called figure axis, line of nodes,
  901. and vertical. See [Edmonds74]_, however note that the symbols alpha
  902. and gamma are swapped in this implementation.
  903. Returns
  904. =======
  905. A matrix representing the corresponding Euler angle rotation (in the basis
  906. of eigenvectors of `J_z`).
  907. .. math ::
  908. \\mathcal{D}_{\\alpha \\beta \\gamma} =
  909. \\exp\\big( \\frac{i\\alpha}{\\hbar} J_z\\big)
  910. \\exp\\big( \\frac{i\\beta}{\\hbar} J_y\\big)
  911. \\exp\\big( \\frac{i\\gamma}{\\hbar} J_z\\big)
  912. such that
  913. .. math ::
  914. \\mathcal{D}^{(J)}_{m',m}(\\alpha, \\beta, \\gamma) =
  915. \\mathtt{wigner_d(J, alpha, beta, gamma)[J-mprime,J-m]}
  916. The components are calculated using the general form [Edmonds74]_,
  917. equation 4.1.12, however note that the angles alpha and gamma are swapped
  918. in this implementation.
  919. Examples
  920. ========
  921. The simplest possible example:
  922. >>> from sympy.physics.wigner import wigner_d
  923. >>> from sympy import Integer, symbols, pprint
  924. >>> half = 1/Integer(2)
  925. >>> alpha, beta, gamma = symbols("alpha, beta, gamma", real=True)
  926. >>> pprint(wigner_d(half, alpha, beta, gamma), use_unicode=True)
  927. ⎡ ⅈ⋅α ⅈ⋅γ ⅈ⋅α -ⅈ⋅γ ⎤
  928. ⎢ ─── ─── ─── ───── ⎥
  929. ⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞ ⎥
  930. ⎢ ℯ ⋅ℯ ⋅cos⎜─⎟ ℯ ⋅ℯ ⋅sin⎜─⎟ ⎥
  931. ⎢ ⎝2⎠ ⎝2⎠ ⎥
  932. ⎢ ⎥
  933. ⎢ -ⅈ⋅α ⅈ⋅γ -ⅈ⋅α -ⅈ⋅γ ⎥
  934. ⎢ ───── ─── ───── ───── ⎥
  935. ⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞⎥
  936. ⎢-ℯ ⋅ℯ ⋅sin⎜─⎟ ℯ ⋅ℯ ⋅cos⎜─⎟⎥
  937. ⎣ ⎝2⎠ ⎝2⎠⎦
  938. """
  939. d = wigner_d_small(J, beta)
  940. M = [J-i for i in range(2*J+1)]
  941. # Mi corresponds to Edmonds' $m'$, and Mj to $m$.
  942. D = [[exp(I*Mi*alpha)*d[i, j]*exp(I*Mj*gamma)
  943. for j, Mj in enumerate(M)] for i, Mi in enumerate(M)]
  944. return ImmutableMatrix(D)