wigner.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  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. Credits and Copyright
  26. =====================
  27. This code was taken from Sage with the permission of all authors:
  28. https://groups.google.com/forum/#!topic/sage-devel/M4NZdu-7O38
  29. Authors
  30. =======
  31. - Jens Rasch (2009-03-24): initial version for Sage
  32. - Jens Rasch (2009-05-31): updated to sage-4.0
  33. - Oscar Gerardo Lazo Arjona (2017-06-18): added Wigner D matrices
  34. Copyright (C) 2008 Jens Rasch <jyr2000@gmail.com>
  35. """
  36. from sympy.concrete.summations import Sum
  37. from sympy.core.add import Add
  38. from sympy.core.function import Function
  39. from sympy.core.numbers import (I, Integer, pi)
  40. from sympy.core.singleton import S
  41. from sympy.core.symbol import Dummy
  42. from sympy.core.sympify import sympify
  43. from sympy.functions.combinatorial.factorials import (binomial, factorial)
  44. from sympy.functions.elementary.exponential import exp
  45. from sympy.functions.elementary.miscellaneous import sqrt
  46. from sympy.functions.elementary.trigonometric import (cos, sin)
  47. from sympy.functions.special.spherical_harmonics import Ynm
  48. from sympy.matrices.dense import zeros
  49. from sympy.matrices.immutable import ImmutableMatrix
  50. # This list of precomputed factorials is needed to massively
  51. # accelerate future calculations of the various coefficients
  52. _Factlist = [1]
  53. def _calc_factlist(nn):
  54. r"""
  55. Function calculates a list of precomputed factorials in order to
  56. massively accelerate future calculations of the various
  57. coefficients.
  58. Parameters
  59. ==========
  60. nn : integer
  61. Highest factorial to be computed.
  62. Returns
  63. =======
  64. list of integers :
  65. The list of precomputed factorials.
  66. Examples
  67. ========
  68. Calculate list of factorials::
  69. sage: from sage.functions.wigner import _calc_factlist
  70. sage: _calc_factlist(10)
  71. [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
  72. """
  73. if nn >= len(_Factlist):
  74. for ii in range(len(_Factlist), int(nn + 1)):
  75. _Factlist.append(_Factlist[ii - 1] * ii)
  76. return _Factlist[:int(nn) + 1]
  77. def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3):
  78. r"""
  79. Calculate the Wigner 3j symbol `\operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)`.
  80. Parameters
  81. ==========
  82. j_1, j_2, j_3, m_1, m_2, m_3 :
  83. Integer or half integer.
  84. Returns
  85. =======
  86. Rational number times the square root of a rational number.
  87. Examples
  88. ========
  89. >>> from sympy.physics.wigner import wigner_3j
  90. >>> wigner_3j(2, 6, 4, 0, 0, 0)
  91. sqrt(715)/143
  92. >>> wigner_3j(2, 6, 4, 0, 0, 1)
  93. 0
  94. It is an error to have arguments that are not integer or half
  95. integer values::
  96. sage: wigner_3j(2.1, 6, 4, 0, 0, 0)
  97. Traceback (most recent call last):
  98. ...
  99. ValueError: j values must be integer or half integer
  100. sage: wigner_3j(2, 6, 4, 1, 0, -1.1)
  101. Traceback (most recent call last):
  102. ...
  103. ValueError: m values must be integer or half integer
  104. Notes
  105. =====
  106. The Wigner 3j symbol obeys the following symmetry rules:
  107. - invariant under any permutation of the columns (with the
  108. exception of a sign change where `J:=j_1+j_2+j_3`):
  109. .. math::
  110. \begin{aligned}
  111. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)
  112. &=\operatorname{Wigner3j}(j_3,j_1,j_2,m_3,m_1,m_2) \\
  113. &=\operatorname{Wigner3j}(j_2,j_3,j_1,m_2,m_3,m_1) \\
  114. &=(-1)^J \operatorname{Wigner3j}(j_3,j_2,j_1,m_3,m_2,m_1) \\
  115. &=(-1)^J \operatorname{Wigner3j}(j_1,j_3,j_2,m_1,m_3,m_2) \\
  116. &=(-1)^J \operatorname{Wigner3j}(j_2,j_1,j_3,m_2,m_1,m_3)
  117. \end{aligned}
  118. - invariant under space inflection, i.e.
  119. .. math::
  120. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,m_3)
  121. =(-1)^J \operatorname{Wigner3j}(j_1,j_2,j_3,-m_1,-m_2,-m_3)
  122. - symmetric with respect to the 72 additional symmetries based on
  123. the work by [Regge58]_
  124. - zero for `j_1`, `j_2`, `j_3` not fulfilling triangle relation
  125. - zero for `m_1 + m_2 + m_3 \neq 0`
  126. - zero for violating any one of the conditions
  127. `j_1 \ge |m_1|`, `j_2 \ge |m_2|`, `j_3 \ge |m_3|`
  128. Algorithm
  129. =========
  130. This function uses the algorithm of [Edmonds74]_ to calculate the
  131. value of the 3j symbol exactly. Note that the formula contains
  132. alternating sums over large factorials and is therefore unsuitable
  133. for finite precision arithmetic and only useful for a computer
  134. algebra system [Rasch03]_.
  135. Authors
  136. =======
  137. - Jens Rasch (2009-03-24): initial version
  138. """
  139. if int(j_1 * 2) != j_1 * 2 or int(j_2 * 2) != j_2 * 2 or \
  140. int(j_3 * 2) != j_3 * 2:
  141. raise ValueError("j values must be integer or half integer")
  142. if int(m_1 * 2) != m_1 * 2 or int(m_2 * 2) != m_2 * 2 or \
  143. int(m_3 * 2) != m_3 * 2:
  144. raise ValueError("m values must be integer or half integer")
  145. if m_1 + m_2 + m_3 != 0:
  146. return S.Zero
  147. prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
  148. m_3 = -m_3
  149. a1 = j_1 + j_2 - j_3
  150. if a1 < 0:
  151. return S.Zero
  152. a2 = j_1 - j_2 + j_3
  153. if a2 < 0:
  154. return S.Zero
  155. a3 = -j_1 + j_2 + j_3
  156. if a3 < 0:
  157. return S.Zero
  158. if (abs(m_1) > j_1) or (abs(m_2) > j_2) or (abs(m_3) > j_3):
  159. return S.Zero
  160. maxfact = max(j_1 + j_2 + j_3 + 1, j_1 + abs(m_1), j_2 + abs(m_2),
  161. j_3 + abs(m_3))
  162. _calc_factlist(int(maxfact))
  163. argsqrt = Integer(_Factlist[int(j_1 + j_2 - j_3)] *
  164. _Factlist[int(j_1 - j_2 + j_3)] *
  165. _Factlist[int(-j_1 + j_2 + j_3)] *
  166. _Factlist[int(j_1 - m_1)] *
  167. _Factlist[int(j_1 + m_1)] *
  168. _Factlist[int(j_2 - m_2)] *
  169. _Factlist[int(j_2 + m_2)] *
  170. _Factlist[int(j_3 - m_3)] *
  171. _Factlist[int(j_3 + m_3)]) / \
  172. _Factlist[int(j_1 + j_2 + j_3 + 1)]
  173. ressqrt = sqrt(argsqrt)
  174. if ressqrt.is_complex or ressqrt.is_infinite:
  175. ressqrt = ressqrt.as_real_imag()[0]
  176. imin = max(-j_3 + j_1 + m_2, -j_3 + j_2 - m_1, 0)
  177. imax = min(j_2 + m_2, j_1 - m_1, j_1 + j_2 - j_3)
  178. sumres = 0
  179. for ii in range(int(imin), int(imax) + 1):
  180. den = _Factlist[ii] * \
  181. _Factlist[int(ii + j_3 - j_1 - m_2)] * \
  182. _Factlist[int(j_2 + m_2 - ii)] * \
  183. _Factlist[int(j_1 - ii - m_1)] * \
  184. _Factlist[int(ii + j_3 - j_2 + m_1)] * \
  185. _Factlist[int(j_1 + j_2 - j_3 - ii)]
  186. sumres = sumres + Integer((-1) ** ii) / den
  187. res = ressqrt * sumres * prefid
  188. return res
  189. def clebsch_gordan(j_1, j_2, j_3, m_1, m_2, m_3):
  190. r"""
  191. Calculates the Clebsch-Gordan coefficient.
  192. `\left\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \right\rangle`.
  193. The reference for this function is [Edmonds74]_.
  194. Parameters
  195. ==========
  196. j_1, j_2, j_3, m_1, m_2, m_3 :
  197. Integer or half integer.
  198. Returns
  199. =======
  200. Rational number times the square root of a rational number.
  201. Examples
  202. ========
  203. >>> from sympy import S
  204. >>> from sympy.physics.wigner import clebsch_gordan
  205. >>> clebsch_gordan(S(3)/2, S(1)/2, 2, S(3)/2, S(1)/2, 2)
  206. 1
  207. >>> clebsch_gordan(S(3)/2, S(1)/2, 1, S(3)/2, -S(1)/2, 1)
  208. sqrt(3)/2
  209. >>> clebsch_gordan(S(3)/2, S(1)/2, 1, -S(1)/2, S(1)/2, 0)
  210. -sqrt(2)/2
  211. Notes
  212. =====
  213. The Clebsch-Gordan coefficient will be evaluated via its relation
  214. to Wigner 3j symbols:
  215. .. math::
  216. \left\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \right\rangle
  217. =(-1)^{j_1-j_2+m_3} \sqrt{2j_3+1}
  218. \operatorname{Wigner3j}(j_1,j_2,j_3,m_1,m_2,-m_3)
  219. See also the documentation on Wigner 3j symbols which exhibit much
  220. higher symmetry relations than the Clebsch-Gordan coefficient.
  221. Authors
  222. =======
  223. - Jens Rasch (2009-03-24): initial version
  224. """
  225. res = (-1) ** sympify(j_1 - j_2 + m_3) * sqrt(2 * j_3 + 1) * \
  226. wigner_3j(j_1, j_2, j_3, m_1, m_2, -m_3)
  227. return res
  228. def _big_delta_coeff(aa, bb, cc, prec=None):
  229. r"""
  230. Calculates the Delta coefficient of the 3 angular momenta for
  231. Racah symbols. Also checks that the differences are of integer
  232. value.
  233. Parameters
  234. ==========
  235. aa :
  236. First angular momentum, integer or half integer.
  237. bb :
  238. Second angular momentum, integer or half integer.
  239. cc :
  240. Third angular momentum, integer or half integer.
  241. prec :
  242. Precision of the ``sqrt()`` calculation.
  243. Returns
  244. =======
  245. double : Value of the Delta coefficient.
  246. Examples
  247. ========
  248. sage: from sage.functions.wigner import _big_delta_coeff
  249. sage: _big_delta_coeff(1,1,1)
  250. 1/2*sqrt(1/6)
  251. """
  252. if int(aa + bb - cc) != (aa + bb - cc):
  253. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  254. if int(aa + cc - bb) != (aa + cc - bb):
  255. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  256. if int(bb + cc - aa) != (bb + cc - aa):
  257. raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
  258. if (aa + bb - cc) < 0:
  259. return S.Zero
  260. if (aa + cc - bb) < 0:
  261. return S.Zero
  262. if (bb + cc - aa) < 0:
  263. return S.Zero
  264. maxfact = max(aa + bb - cc, aa + cc - bb, bb + cc - aa, aa + bb + cc + 1)
  265. _calc_factlist(maxfact)
  266. argsqrt = Integer(_Factlist[int(aa + bb - cc)] *
  267. _Factlist[int(aa + cc - bb)] *
  268. _Factlist[int(bb + cc - aa)]) / \
  269. Integer(_Factlist[int(aa + bb + cc + 1)])
  270. ressqrt = sqrt(argsqrt)
  271. if prec:
  272. ressqrt = ressqrt.evalf(prec).as_real_imag()[0]
  273. return ressqrt
  274. def racah(aa, bb, cc, dd, ee, ff, prec=None):
  275. r"""
  276. Calculate the Racah symbol `W(a,b,c,d;e,f)`.
  277. Parameters
  278. ==========
  279. a, ..., f :
  280. Integer or half integer.
  281. prec :
  282. Precision, default: ``None``. Providing a precision can
  283. drastically speed up the calculation.
  284. Returns
  285. =======
  286. Rational number times the square root of a rational number
  287. (if ``prec=None``), or real number if a precision is given.
  288. Examples
  289. ========
  290. >>> from sympy.physics.wigner import racah
  291. >>> racah(3,3,3,3,3,3)
  292. -1/14
  293. Notes
  294. =====
  295. The Racah symbol is related to the Wigner 6j symbol:
  296. .. math::
  297. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  298. =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
  299. Please see the 6j symbol for its much richer symmetries and for
  300. additional properties.
  301. Algorithm
  302. =========
  303. This function uses the algorithm of [Edmonds74]_ to calculate the
  304. value of the 6j symbol exactly. Note that the formula contains
  305. alternating sums over large factorials and is therefore unsuitable
  306. for finite precision arithmetic and only useful for a computer
  307. algebra system [Rasch03]_.
  308. Authors
  309. =======
  310. - Jens Rasch (2009-03-24): initial version
  311. """
  312. prefac = _big_delta_coeff(aa, bb, ee, prec) * \
  313. _big_delta_coeff(cc, dd, ee, prec) * \
  314. _big_delta_coeff(aa, cc, ff, prec) * \
  315. _big_delta_coeff(bb, dd, ff, prec)
  316. if prefac == 0:
  317. return S.Zero
  318. imin = max(aa + bb + ee, cc + dd + ee, aa + cc + ff, bb + dd + ff)
  319. imax = min(aa + bb + cc + dd, aa + dd + ee + ff, bb + cc + ee + ff)
  320. maxfact = max(imax + 1, aa + bb + cc + dd, aa + dd + ee + ff,
  321. bb + cc + ee + ff)
  322. _calc_factlist(maxfact)
  323. sumres = 0
  324. for kk in range(int(imin), int(imax) + 1):
  325. den = _Factlist[int(kk - aa - bb - ee)] * \
  326. _Factlist[int(kk - cc - dd - ee)] * \
  327. _Factlist[int(kk - aa - cc - ff)] * \
  328. _Factlist[int(kk - bb - dd - ff)] * \
  329. _Factlist[int(aa + bb + cc + dd - kk)] * \
  330. _Factlist[int(aa + dd + ee + ff - kk)] * \
  331. _Factlist[int(bb + cc + ee + ff - kk)]
  332. sumres = sumres + Integer((-1) ** kk * _Factlist[kk + 1]) / den
  333. res = prefac * sumres * (-1) ** int(aa + bb + cc + dd)
  334. return res
  335. def wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None):
  336. r"""
  337. Calculate the Wigner 6j symbol `\operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)`.
  338. Parameters
  339. ==========
  340. j_1, ..., j_6 :
  341. Integer or half integer.
  342. prec :
  343. Precision, default: ``None``. Providing a precision can
  344. drastically speed up the calculation.
  345. Returns
  346. =======
  347. Rational number times the square root of a rational number
  348. (if ``prec=None``), or real number if a precision is given.
  349. Examples
  350. ========
  351. >>> from sympy.physics.wigner import wigner_6j
  352. >>> wigner_6j(3,3,3,3,3,3)
  353. -1/14
  354. >>> wigner_6j(5,5,5,5,5,5)
  355. 1/52
  356. It is an error to have arguments that are not integer or half
  357. integer values or do not fulfill the triangle relation::
  358. sage: wigner_6j(2.5,2.5,2.5,2.5,2.5,2.5)
  359. Traceback (most recent call last):
  360. ...
  361. ValueError: j values must be integer or half integer and fulfill the triangle relation
  362. sage: wigner_6j(0.5,0.5,1.1,0.5,0.5,1.1)
  363. Traceback (most recent call last):
  364. ...
  365. ValueError: j values must be integer or half integer and fulfill the triangle relation
  366. Notes
  367. =====
  368. The Wigner 6j symbol is related to the Racah symbol but exhibits
  369. more symmetries as detailed below.
  370. .. math::
  371. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  372. =(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
  373. The Wigner 6j symbol obeys the following symmetry rules:
  374. - Wigner 6j symbols are left invariant under any permutation of
  375. the columns:
  376. .. math::
  377. \begin{aligned}
  378. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  379. &=\operatorname{Wigner6j}(j_3,j_1,j_2,j_6,j_4,j_5) \\
  380. &=\operatorname{Wigner6j}(j_2,j_3,j_1,j_5,j_6,j_4) \\
  381. &=\operatorname{Wigner6j}(j_3,j_2,j_1,j_6,j_5,j_4) \\
  382. &=\operatorname{Wigner6j}(j_1,j_3,j_2,j_4,j_6,j_5) \\
  383. &=\operatorname{Wigner6j}(j_2,j_1,j_3,j_5,j_4,j_6)
  384. \end{aligned}
  385. - They are invariant under the exchange of the upper and lower
  386. arguments in each of any two columns, i.e.
  387. .. math::
  388. \operatorname{Wigner6j}(j_1,j_2,j_3,j_4,j_5,j_6)
  389. =\operatorname{Wigner6j}(j_1,j_5,j_6,j_4,j_2,j_3)
  390. =\operatorname{Wigner6j}(j_4,j_2,j_6,j_1,j_5,j_3)
  391. =\operatorname{Wigner6j}(j_4,j_5,j_3,j_1,j_2,j_6)
  392. - additional 6 symmetries [Regge59]_ giving rise to 144 symmetries
  393. in total
  394. - only non-zero if any triple of `j`'s fulfill a triangle relation
  395. Algorithm
  396. =========
  397. This function uses the algorithm of [Edmonds74]_ to calculate the
  398. value of the 6j symbol exactly. Note that the formula contains
  399. alternating sums over large factorials and is therefore unsuitable
  400. for finite precision arithmetic and only useful for a computer
  401. algebra system [Rasch03]_.
  402. """
  403. res = (-1) ** int(j_1 + j_2 + j_4 + j_5) * \
  404. racah(j_1, j_2, j_5, j_4, j_3, j_6, prec)
  405. return res
  406. def wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None):
  407. r"""
  408. Calculate the Wigner 9j symbol
  409. `\operatorname{Wigner9j}(j_1,j_2,j_3,j_4,j_5,j_6,j_7,j_8,j_9)`.
  410. Parameters
  411. ==========
  412. j_1, ..., j_9 :
  413. Integer or half integer.
  414. prec : precision, default
  415. ``None``. Providing a precision can
  416. drastically speed up the calculation.
  417. Returns
  418. =======
  419. Rational number times the square root of a rational number
  420. (if ``prec=None``), or real number if a precision is given.
  421. Examples
  422. ========
  423. >>> from sympy.physics.wigner import wigner_9j
  424. >>> wigner_9j(1,1,1, 1,1,1, 1,1,0, prec=64) # ==1/18
  425. 0.05555555...
  426. >>> wigner_9j(1/2,1/2,0, 1/2,3/2,1, 0,1,1, prec=64) # ==1/6
  427. 0.1666666...
  428. It is an error to have arguments that are not integer or half
  429. integer values or do not fulfill the triangle relation::
  430. sage: wigner_9j(0.5,0.5,0.5, 0.5,0.5,0.5, 0.5,0.5,0.5,prec=64)
  431. Traceback (most recent call last):
  432. ...
  433. ValueError: j values must be integer or half integer and fulfill the triangle relation
  434. sage: wigner_9j(1,1,1, 0.5,1,1.5, 0.5,1,2.5,prec=64)
  435. Traceback (most recent call last):
  436. ...
  437. ValueError: j values must be integer or half integer and fulfill the triangle relation
  438. Algorithm
  439. =========
  440. This function uses the algorithm of [Edmonds74]_ to calculate the
  441. value of the 3j symbol exactly. Note that the formula contains
  442. alternating sums over large factorials and is therefore unsuitable
  443. for finite precision arithmetic and only useful for a computer
  444. algebra system [Rasch03]_.
  445. """
  446. imax = int(min(j_1 + j_9, j_2 + j_6, j_4 + j_8) * 2)
  447. imin = imax % 2
  448. sumres = 0
  449. for kk in range(imin, int(imax) + 1, 2):
  450. sumres = sumres + (kk + 1) * \
  451. racah(j_1, j_2, j_9, j_6, j_3, kk / 2, prec) * \
  452. racah(j_4, j_6, j_8, j_2, j_5, kk / 2, prec) * \
  453. racah(j_1, j_4, j_9, j_8, j_7, kk / 2, prec)
  454. return sumres
  455. def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None):
  456. r"""
  457. Calculate the Gaunt coefficient.
  458. Explanation
  459. ===========
  460. The Gaunt coefficient is defined as the integral over three
  461. spherical harmonics:
  462. .. math::
  463. \begin{aligned}
  464. \operatorname{Gaunt}(l_1,l_2,l_3,m_1,m_2,m_3)
  465. &=\int Y_{l_1,m_1}(\Omega)
  466. Y_{l_2,m_2}(\Omega) Y_{l_3,m_3}(\Omega) \,d\Omega \\
  467. &=\sqrt{\frac{(2l_1+1)(2l_2+1)(2l_3+1)}{4\pi}}
  468. \operatorname{Wigner3j}(l_1,l_2,l_3,0,0,0)
  469. \operatorname{Wigner3j}(l_1,l_2,l_3,m_1,m_2,m_3)
  470. \end{aligned}
  471. Parameters
  472. ==========
  473. l_1, l_2, l_3, m_1, m_2, m_3 :
  474. Integer.
  475. prec - precision, default: ``None``.
  476. Providing a precision can
  477. drastically speed up the calculation.
  478. Returns
  479. =======
  480. Rational number times the square root of a rational number
  481. (if ``prec=None``), or real number if a precision is given.
  482. Examples
  483. ========
  484. >>> from sympy.physics.wigner import gaunt
  485. >>> gaunt(1,0,1,1,0,-1)
  486. -1/(2*sqrt(pi))
  487. >>> gaunt(1000,1000,1200,9,3,-12).n(64)
  488. 0.00689500421922113448...
  489. It is an error to use non-integer values for `l` and `m`::
  490. sage: gaunt(1.2,0,1.2,0,0,0)
  491. Traceback (most recent call last):
  492. ...
  493. ValueError: l values must be integer
  494. sage: gaunt(1,0,1,1.1,0,-1.1)
  495. Traceback (most recent call last):
  496. ...
  497. ValueError: m values must be integer
  498. Notes
  499. =====
  500. The Gaunt coefficient obeys the following symmetry rules:
  501. - invariant under any permutation of the columns
  502. .. math::
  503. \begin{aligned}
  504. Y(l_1,l_2,l_3,m_1,m_2,m_3)
  505. &=Y(l_3,l_1,l_2,m_3,m_1,m_2) \\
  506. &=Y(l_2,l_3,l_1,m_2,m_3,m_1) \\
  507. &=Y(l_3,l_2,l_1,m_3,m_2,m_1) \\
  508. &=Y(l_1,l_3,l_2,m_1,m_3,m_2) \\
  509. &=Y(l_2,l_1,l_3,m_2,m_1,m_3)
  510. \end{aligned}
  511. - invariant under space inflection, i.e.
  512. .. math::
  513. Y(l_1,l_2,l_3,m_1,m_2,m_3)
  514. =Y(l_1,l_2,l_3,-m_1,-m_2,-m_3)
  515. - symmetric with respect to the 72 Regge symmetries as inherited
  516. for the `3j` symbols [Regge58]_
  517. - zero for `l_1`, `l_2`, `l_3` not fulfilling triangle relation
  518. - zero for violating any one of the conditions: `l_1 \ge |m_1|`,
  519. `l_2 \ge |m_2|`, `l_3 \ge |m_3|`
  520. - non-zero only for an even sum of the `l_i`, i.e.
  521. `L = l_1 + l_2 + l_3 = 2n` for `n` in `\mathbb{N}`
  522. Algorithms
  523. ==========
  524. This function uses the algorithm of [Liberatodebrito82]_ to
  525. calculate the value of the Gaunt coefficient exactly. Note that
  526. the formula contains alternating sums over large factorials and is
  527. therefore unsuitable for finite precision arithmetic and only
  528. useful for a computer algebra system [Rasch03]_.
  529. Authors
  530. =======
  531. Jens Rasch (2009-03-24): initial version for Sage.
  532. """
  533. if int(l_1) != l_1 or int(l_2) != l_2 or int(l_3) != l_3:
  534. raise ValueError("l values must be integer")
  535. if int(m_1) != m_1 or int(m_2) != m_2 or int(m_3) != m_3:
  536. raise ValueError("m values must be integer")
  537. sumL = l_1 + l_2 + l_3
  538. bigL = sumL // 2
  539. a1 = l_1 + l_2 - l_3
  540. if a1 < 0:
  541. return S.Zero
  542. a2 = l_1 - l_2 + l_3
  543. if a2 < 0:
  544. return S.Zero
  545. a3 = -l_1 + l_2 + l_3
  546. if a3 < 0:
  547. return S.Zero
  548. if sumL % 2:
  549. return S.Zero
  550. if (m_1 + m_2 + m_3) != 0:
  551. return S.Zero
  552. if (abs(m_1) > l_1) or (abs(m_2) > l_2) or (abs(m_3) > l_3):
  553. return S.Zero
  554. imin = max(-l_3 + l_1 + m_2, -l_3 + l_2 - m_1, 0)
  555. imax = min(l_2 + m_2, l_1 - m_1, l_1 + l_2 - l_3)
  556. maxfact = max(l_1 + l_2 + l_3 + 1, imax + 1)
  557. _calc_factlist(maxfact)
  558. argsqrt = (2 * l_1 + 1) * (2 * l_2 + 1) * (2 * l_3 + 1) * \
  559. _Factlist[l_1 - m_1] * _Factlist[l_1 + m_1] * _Factlist[l_2 - m_2] * \
  560. _Factlist[l_2 + m_2] * _Factlist[l_3 - m_3] * _Factlist[l_3 + m_3] / \
  561. (4*pi)
  562. ressqrt = sqrt(argsqrt)
  563. prefac = Integer(_Factlist[bigL] * _Factlist[l_2 - l_1 + l_3] *
  564. _Factlist[l_1 - l_2 + l_3] * _Factlist[l_1 + l_2 - l_3])/ \
  565. _Factlist[2 * bigL + 1]/ \
  566. (_Factlist[bigL - l_1] *
  567. _Factlist[bigL - l_2] * _Factlist[bigL - l_3])
  568. sumres = 0
  569. for ii in range(int(imin), int(imax) + 1):
  570. den = _Factlist[ii] * _Factlist[ii + l_3 - l_1 - m_2] * \
  571. _Factlist[l_2 + m_2 - ii] * _Factlist[l_1 - ii - m_1] * \
  572. _Factlist[ii + l_3 - l_2 + m_1] * _Factlist[l_1 + l_2 - l_3 - ii]
  573. sumres = sumres + Integer((-1) ** ii) / den
  574. res = ressqrt * prefac * sumres * Integer((-1) ** (bigL + l_3 + m_1 - m_2))
  575. if prec is not None:
  576. res = res.n(prec)
  577. return res
  578. class Wigner3j(Function):
  579. def doit(self, **hints):
  580. if all(obj.is_number for obj in self.args):
  581. return wigner_3j(*self.args)
  582. else:
  583. return self
  584. def dot_rot_grad_Ynm(j, p, l, m, theta, phi):
  585. r"""
  586. Returns dot product of rotational gradients of spherical harmonics.
  587. Explanation
  588. ===========
  589. This function returns the right hand side of the following expression:
  590. .. math ::
  591. \vec{R}Y{_j^{p}} \cdot \vec{R}Y{_l^{m}} = (-1)^{m+p}
  592. \sum\limits_{k=|l-j|}^{l+j}Y{_k^{m+p}} * \alpha_{l,m,j,p,k} *
  593. \frac{1}{2} (k^2-j^2-l^2+k-j-l)
  594. Arguments
  595. =========
  596. j, p, l, m .... indices in spherical harmonics (expressions or integers)
  597. theta, phi .... angle arguments in spherical harmonics
  598. Example
  599. =======
  600. >>> from sympy import symbols
  601. >>> from sympy.physics.wigner import dot_rot_grad_Ynm
  602. >>> theta, phi = symbols("theta phi")
  603. >>> dot_rot_grad_Ynm(3, 2, 2, 0, theta, phi).doit()
  604. 3*sqrt(55)*Ynm(5, 2, theta, phi)/(11*sqrt(pi))
  605. """
  606. j = sympify(j)
  607. p = sympify(p)
  608. l = sympify(l)
  609. m = sympify(m)
  610. theta = sympify(theta)
  611. phi = sympify(phi)
  612. k = Dummy("k")
  613. def alpha(l,m,j,p,k):
  614. return sqrt((2*l+1)*(2*j+1)*(2*k+1)/(4*pi)) * \
  615. Wigner3j(j, l, k, S.Zero, S.Zero, S.Zero) * \
  616. Wigner3j(j, l, k, p, m, -m-p)
  617. return (S.NegativeOne)**(m+p) * Sum(Ynm(k, m+p, theta, phi) * alpha(l,m,j,p,k) / 2 \
  618. *(k**2-j**2-l**2+k-j-l), (k, abs(l-j), l+j))
  619. def wigner_d_small(J, beta):
  620. """Return the small Wigner d matrix for angular momentum J.
  621. Explanation
  622. ===========
  623. J : An integer, half-integer, or SymPy symbol for the total angular
  624. momentum of the angular momentum space being rotated.
  625. beta : A real number representing the Euler angle of rotation about
  626. the so-called line of nodes. See [Edmonds74]_.
  627. Returns
  628. =======
  629. A matrix representing the corresponding Euler angle rotation( in the basis
  630. of eigenvectors of `J_z`).
  631. .. math ::
  632. \\mathcal{d}_{\\beta} = \\exp\\big( \\frac{i\\beta}{\\hbar} J_y\\big)
  633. The components are calculated using the general form [Edmonds74]_,
  634. equation 4.1.15.
  635. Examples
  636. ========
  637. >>> from sympy import Integer, symbols, pi, pprint
  638. >>> from sympy.physics.wigner import wigner_d_small
  639. >>> half = 1/Integer(2)
  640. >>> beta = symbols("beta", real=True)
  641. >>> pprint(wigner_d_small(half, beta), use_unicode=True)
  642. ⎡ ⎛β⎞ ⎛β⎞⎤
  643. ⎢cos⎜─⎟ sin⎜─⎟⎥
  644. ⎢ ⎝2⎠ ⎝2⎠⎥
  645. ⎢ ⎥
  646. ⎢ ⎛β⎞ ⎛β⎞⎥
  647. ⎢-sin⎜─⎟ cos⎜─⎟⎥
  648. ⎣ ⎝2⎠ ⎝2⎠⎦
  649. >>> pprint(wigner_d_small(2*half, beta), use_unicode=True)
  650. ⎡ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎤
  651. ⎢ cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟ sin ⎜─⎟ ⎥
  652. ⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎥
  653. ⎢ ⎥
  654. ⎢ ⎛β⎞ ⎛β⎞ 2⎛β⎞ 2⎛β⎞ ⎛β⎞ ⎛β⎞⎥
  655. ⎢-√2⋅sin⎜─⎟⋅cos⎜─⎟ - sin ⎜─⎟ + cos ⎜─⎟ √2⋅sin⎜─⎟⋅cos⎜─⎟⎥
  656. ⎢ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠⎥
  657. ⎢ ⎥
  658. ⎢ 2⎛β⎞ ⎛β⎞ ⎛β⎞ 2⎛β⎞ ⎥
  659. ⎢ sin ⎜─⎟ -√2⋅sin⎜─⎟⋅cos⎜─⎟ cos ⎜─⎟ ⎥
  660. ⎣ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎝2⎠ ⎦
  661. From table 4 in [Edmonds74]_
  662. >>> pprint(wigner_d_small(half, beta).subs({beta:pi/2}), use_unicode=True)
  663. ⎡ √2 √2⎤
  664. ⎢ ── ──⎥
  665. ⎢ 2 2 ⎥
  666. ⎢ ⎥
  667. ⎢-√2 √2⎥
  668. ⎢──── ──⎥
  669. ⎣ 2 2 ⎦
  670. >>> pprint(wigner_d_small(2*half, beta).subs({beta:pi/2}),
  671. ... use_unicode=True)
  672. ⎡ √2 ⎤
  673. ⎢1/2 ── 1/2⎥
  674. ⎢ 2 ⎥
  675. ⎢ ⎥
  676. ⎢-√2 √2 ⎥
  677. ⎢──── 0 ── ⎥
  678. ⎢ 2 2 ⎥
  679. ⎢ ⎥
  680. ⎢ -√2 ⎥
  681. ⎢1/2 ──── 1/2⎥
  682. ⎣ 2 ⎦
  683. >>> pprint(wigner_d_small(3*half, beta).subs({beta:pi/2}),
  684. ... use_unicode=True)
  685. ⎡ √2 √6 √6 √2⎤
  686. ⎢ ── ── ── ──⎥
  687. ⎢ 4 4 4 4 ⎥
  688. ⎢ ⎥
  689. ⎢-√6 -√2 √2 √6⎥
  690. ⎢──── ──── ── ──⎥
  691. ⎢ 4 4 4 4 ⎥
  692. ⎢ ⎥
  693. ⎢ √6 -√2 -√2 √6⎥
  694. ⎢ ── ──── ──── ──⎥
  695. ⎢ 4 4 4 4 ⎥
  696. ⎢ ⎥
  697. ⎢-√2 √6 -√6 √2⎥
  698. ⎢──── ── ──── ──⎥
  699. ⎣ 4 4 4 4 ⎦
  700. >>> pprint(wigner_d_small(4*half, beta).subs({beta:pi/2}),
  701. ... use_unicode=True)
  702. ⎡ √6 ⎤
  703. ⎢1/4 1/2 ── 1/2 1/4⎥
  704. ⎢ 4 ⎥
  705. ⎢ ⎥
  706. ⎢-1/2 -1/2 0 1/2 1/2⎥
  707. ⎢ ⎥
  708. ⎢ √6 √6 ⎥
  709. ⎢ ── 0 -1/2 0 ── ⎥
  710. ⎢ 4 4 ⎥
  711. ⎢ ⎥
  712. ⎢-1/2 1/2 0 -1/2 1/2⎥
  713. ⎢ ⎥
  714. ⎢ √6 ⎥
  715. ⎢1/4 -1/2 ── -1/2 1/4⎥
  716. ⎣ 4 ⎦
  717. """
  718. M = [J-i for i in range(2*J+1)]
  719. d = zeros(2*J+1)
  720. for i, Mi in enumerate(M):
  721. for j, Mj in enumerate(M):
  722. # We get the maximum and minimum value of sigma.
  723. sigmamax = max([-Mi-Mj, J-Mj])
  724. sigmamin = min([0, J-Mi])
  725. dij = sqrt(factorial(J+Mi)*factorial(J-Mi) /
  726. factorial(J+Mj)/factorial(J-Mj))
  727. terms = [(-1)**(J-Mi-s) *
  728. binomial(J+Mj, J-Mi-s) *
  729. binomial(J-Mj, s) *
  730. cos(beta/2)**(2*s+Mi+Mj) *
  731. sin(beta/2)**(2*J-2*s-Mj-Mi)
  732. for s in range(sigmamin, sigmamax+1)]
  733. d[i, j] = dij*Add(*terms)
  734. return ImmutableMatrix(d)
  735. def wigner_d(J, alpha, beta, gamma):
  736. """Return the Wigner D matrix for angular momentum J.
  737. Explanation
  738. ===========
  739. J :
  740. An integer, half-integer, or SymPy symbol for the total angular
  741. momentum of the angular momentum space being rotated.
  742. alpha, beta, gamma - Real numbers representing the Euler.
  743. Angles of rotation about the so-called vertical, line of nodes, and
  744. figure axes. See [Edmonds74]_.
  745. Returns
  746. =======
  747. A matrix representing the corresponding Euler angle rotation( in the basis
  748. of eigenvectors of `J_z`).
  749. .. math ::
  750. \\mathcal{D}_{\\alpha \\beta \\gamma} =
  751. \\exp\\big( \\frac{i\\alpha}{\\hbar} J_z\\big)
  752. \\exp\\big( \\frac{i\\beta}{\\hbar} J_y\\big)
  753. \\exp\\big( \\frac{i\\gamma}{\\hbar} J_z\\big)
  754. The components are calculated using the general form [Edmonds74]_,
  755. equation 4.1.12.
  756. Examples
  757. ========
  758. The simplest possible example:
  759. >>> from sympy.physics.wigner import wigner_d
  760. >>> from sympy import Integer, symbols, pprint
  761. >>> half = 1/Integer(2)
  762. >>> alpha, beta, gamma = symbols("alpha, beta, gamma", real=True)
  763. >>> pprint(wigner_d(half, alpha, beta, gamma), use_unicode=True)
  764. ⎡ ⅈ⋅α ⅈ⋅γ ⅈ⋅α -ⅈ⋅γ ⎤
  765. ⎢ ─── ─── ─── ───── ⎥
  766. ⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞ ⎥
  767. ⎢ ℯ ⋅ℯ ⋅cos⎜─⎟ ℯ ⋅ℯ ⋅sin⎜─⎟ ⎥
  768. ⎢ ⎝2⎠ ⎝2⎠ ⎥
  769. ⎢ ⎥
  770. ⎢ -ⅈ⋅α ⅈ⋅γ -ⅈ⋅α -ⅈ⋅γ ⎥
  771. ⎢ ───── ─── ───── ───── ⎥
  772. ⎢ 2 2 ⎛β⎞ 2 2 ⎛β⎞⎥
  773. ⎢-ℯ ⋅ℯ ⋅sin⎜─⎟ ℯ ⋅ℯ ⋅cos⎜─⎟⎥
  774. ⎣ ⎝2⎠ ⎝2⎠⎦
  775. """
  776. d = wigner_d_small(J, beta)
  777. M = [J-i for i in range(2*J+1)]
  778. D = [[exp(I*Mi*alpha)*d[i, j]*exp(I*Mj*gamma)
  779. for j, Mj in enumerate(M)] for i, Mi in enumerate(M)]
  780. return ImmutableMatrix(D)