Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/functions/wigner.py
4056 views
1
r"""
2
Wigner, Clebsch-Gordan, Racah, and Gaunt coefficients
3
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
9
Please see the description of the individual functions for further
10
details and examples.
11
12
REFERENCES:
13
14
.. [Rasch03] J. Rasch and A. C. H. Yu, 'Efficient Storage Scheme for
15
Pre-calculated Wigner 3j, 6j and Gaunt Coefficients', SIAM
16
J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003)
17
18
AUTHORS:
19
20
- Jens Rasch (2009-03-24): initial version for Sage
21
22
- Jens Rasch (2009-05-31): updated to sage-4.0
23
"""
24
25
#***********************************************************************
26
# Copyright (C) 2008 Jens Rasch <[email protected]>
27
#
28
# Distributed under the terms of the GNU General Public License (GPL)
29
# http://www.gnu.org/licenses/
30
#***********************************************************************
31
32
from sage.rings.complex_number import ComplexNumber
33
from sage.rings.integer import Integer
34
from sage.rings.finite_rings.integer_mod import Mod
35
from sage.symbolic.constants import pi
36
37
# This list of precomputed factorials is needed to massively
38
# accelerate future calculations of the various coefficients
39
_Factlist=[1]
40
41
def _calc_factlist(nn):
42
r"""
43
Function calculates a list of precomputed factorials in order to
44
massively accelerate future calculations of the various
45
coefficients.
46
47
INPUT:
48
49
- ``nn`` - integer, highest factorial to be computed
50
51
OUTPUT:
52
53
list of integers -- the list of precomputed factorials
54
55
EXAMPLES:
56
57
Calculate list of factorials::
58
59
sage: from sage.functions.wigner import _calc_factlist
60
sage: _calc_factlist(10)
61
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]
62
"""
63
if nn >= len(_Factlist):
64
for ii in range(len(_Factlist), nn + 1):
65
_Factlist.append(_Factlist[ii - 1] * ii)
66
return _Factlist[:Integer(nn) + 1]
67
68
69
def wigner_3j(j_1, j_2, j_3, m_1, m_2, m_3, prec=None):
70
r"""
71
Calculate the Wigner 3j symbol `Wigner3j(j_1,j_2,j_3,m_1,m_2,m_3)`.
72
73
INPUT:
74
75
- ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` - integer or half integer
76
77
- ``prec`` - precision, default: ``None``. Providing a precision can
78
drastically speed up the calculation.
79
80
OUTPUT:
81
82
Rational number times the square root of a rational number
83
(if ``prec=None``), or real number if a precision is given.
84
85
EXAMPLES::
86
87
sage: wigner_3j(2, 6, 4, 0, 0, 0)
88
sqrt(5/143)
89
sage: wigner_3j(2, 6, 4, 0, 0, 1)
90
0
91
sage: wigner_3j(0.5, 0.5, 1, 0.5, -0.5, 0)
92
sqrt(1/6)
93
sage: wigner_3j(40, 100, 60, -10, 60, -50)
94
95608/18702538494885*sqrt(21082735836735314343364163310/220491455010479533763)
95
sage: wigner_3j(2500, 2500, 5000, 2488, 2400, -4888, prec=64)
96
7.60424456883448589e-12
97
98
It is an error to have arguments that are not integer or half
99
integer values::
100
101
sage: wigner_3j(2.1, 6, 4, 0, 0, 0)
102
Traceback (most recent call last):
103
...
104
ValueError: j values must be integer or half integer
105
sage: wigner_3j(2, 6, 4, 1, 0, -1.1)
106
Traceback (most recent call last):
107
...
108
ValueError: m values must be integer or half integer
109
110
NOTES:
111
112
The Wigner 3j symbol obeys the following symmetry rules:
113
114
- invariant under any permutation of the columns (with the
115
exception of a sign change where `J:=j_1+j_2+j_3`):
116
117
.. math::
118
119
Wigner3j(j_1,j_2,j_3,m_1,m_2,m_3)
120
=Wigner3j(j_3,j_1,j_2,m_3,m_1,m_2)
121
=Wigner3j(j_2,j_3,j_1,m_2,m_3,m_1)
122
=(-1)^J Wigner3j(j_3,j_2,j_1,m_3,m_2,m_1)
123
=(-1)^J Wigner3j(j_1,j_3,j_2,m_1,m_3,m_2)
124
=(-1)^J Wigner3j(j_2,j_1,j_3,m_2,m_1,m_3)
125
126
- invariant under space inflection, i.e.
127
128
.. math::
129
130
Wigner3j(j_1,j_2,j_3,m_1,m_2,m_3)
131
=(-1)^J Wigner3j(j_1,j_2,j_3,-m_1,-m_2,-m_3)
132
133
- symmetric with respect to the 72 additional symmetries based on
134
the work by [Regge58]_
135
136
- zero for `j_1`, `j_2`, `j_3` not fulfilling triangle relation
137
138
- zero for `m_1 + m_2 + m_3 \neq 0`
139
140
- zero for violating any one of the conditions
141
`j_1 \ge |m_1|`, `j_2 \ge |m_2|`, `j_3 \ge |m_3|`
142
143
ALGORITHM:
144
145
This function uses the algorithm of [Edmonds74]_ to calculate the
146
value of the 3j symbol exactly. Note that the formula contains
147
alternating sums over large factorials and is therefore unsuitable
148
for finite precision arithmetic and only useful for a computer
149
algebra system [Rasch03]_.
150
151
REFERENCES:
152
153
.. [Regge58] 'Symmetry Properties of Clebsch-Gordan Coefficients',
154
T. Regge, Nuovo Cimento, Volume 10, pp. 544 (1958)
155
156
.. [Edmonds74] 'Angular Momentum in Quantum Mechanics',
157
A. R. Edmonds, Princeton University Press (1974)
158
159
AUTHORS:
160
161
- Jens Rasch (2009-03-24): initial version
162
"""
163
if int(j_1 * 2) != j_1 * 2 or int(j_2 * 2) != j_2 * 2 or \
164
int(j_3 * 2) != j_3 * 2:
165
raise ValueError("j values must be integer or half integer")
166
if int(m_1 * 2) != m_1 * 2 or int(m_2 * 2) != m_2 * 2 or \
167
int(m_3 * 2) != m_3 * 2:
168
raise ValueError("m values must be integer or half integer")
169
if m_1 + m_2 + m_3 != 0:
170
return 0
171
prefid = Integer((-1) ** int(j_1 - j_2 - m_3))
172
m_3 = -m_3
173
a1 = j_1 + j_2 - j_3
174
if a1 < 0:
175
return 0
176
a2 = j_1 - j_2 + j_3
177
if a2 < 0:
178
return 0
179
a3 = -j_1 + j_2 + j_3
180
if a3 < 0:
181
return 0
182
if (abs(m_1) > j_1) or (abs(m_2) > j_2) or (abs(m_3) > j_3):
183
return 0
184
185
maxfact = max(j_1 + j_2 + j_3 + 1, j_1 + abs(m_1), j_2 + abs(m_2), \
186
j_3 + abs(m_3))
187
_calc_factlist(maxfact)
188
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
200
ressqrt = argsqrt.sqrt(prec)
201
if type(ressqrt) is ComplexNumber:
202
ressqrt = ressqrt.real()
203
204
imin = max(-j_3 + j_1 + m_2, -j_3 + j_2 - m_1, 0)
205
imax = min(j_2 + m_2, j_1 - m_1, j_1 + j_2 - j_3)
206
sumres = 0
207
for ii in range(imin, imax + 1):
208
den = _Factlist[ii] * \
209
_Factlist[int(ii + j_3 - j_1 - m_2)] * \
210
_Factlist[int(j_2 + m_2 - ii)] * \
211
_Factlist[int(j_1 - ii - m_1)] * \
212
_Factlist[int(ii + j_3 - j_2 + m_1)] * \
213
_Factlist[int(j_1 + j_2 - j_3 - ii)]
214
sumres = sumres + Integer((-1) ** ii) / den
215
216
res = ressqrt * sumres * prefid
217
return res
218
219
220
def clebsch_gordan(j_1, j_2, j_3, m_1, m_2, m_3, prec=None):
221
r"""
222
Calculates the Clebsch-Gordan coefficient
223
`\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \rangle`.
224
225
The reference for this function is [Edmonds74]_.
226
227
INPUT:
228
229
- ``j_1``, ``j_2``, ``j_3``, ``m_1``, ``m_2``, ``m_3`` - integer or half integer
230
231
- ``prec`` - precision, default: ``None``. Providing a precision can
232
drastically speed up the calculation.
233
234
OUTPUT:
235
236
Rational number times the square root of a rational number
237
(if ``prec=None``), or real number if a precision is given.
238
239
EXAMPLES::
240
241
sage: simplify(clebsch_gordan(3/2,1/2,2, 3/2,1/2,2))
242
1
243
sage: clebsch_gordan(1.5,0.5,1, 1.5,-0.5,1)
244
1/2*sqrt(3)
245
sage: clebsch_gordan(3/2,1/2,1, -1/2,1/2,0)
246
-sqrt(1/6)*sqrt(3)
247
248
NOTES:
249
250
The Clebsch-Gordan coefficient will be evaluated via its relation
251
to Wigner 3j symbols:
252
253
.. math::
254
255
\langle j_1 m_1 \; j_2 m_2 | j_3 m_3 \rangle
256
=(-1)^{j_1-j_2+m_3} \sqrt{2j_3+1} \;
257
Wigner3j(j_1,j_2,j_3,m_1,m_2,-m_3)
258
259
See also the documentation on Wigner 3j symbols which exhibit much
260
higher symmetry relations than the Clebsch-Gordan coefficient.
261
262
AUTHORS:
263
264
- Jens Rasch (2009-03-24): initial version
265
"""
266
res = (-1) ** int(j_1 - j_2 + m_3) * (2 * j_3 + 1).sqrt(prec) * \
267
wigner_3j(j_1, j_2, j_3, m_1, m_2, -m_3, prec)
268
return res
269
270
271
def _big_delta_coeff(aa, bb, cc, prec=None):
272
r"""
273
Calculates the Delta coefficient of the 3 angular momenta for
274
Racah symbols. Also checks that the differences are of integer
275
value.
276
277
INPUT:
278
279
- ``aa`` - first angular momentum, integer or half integer
280
281
- ``bb`` - second angular momentum, integer or half integer
282
283
- ``cc`` - third angular momentum, integer or half integer
284
285
- ``prec`` - precision of the ``sqrt()`` calculation
286
287
OUTPUT:
288
289
double - Value of the Delta coefficient
290
291
EXAMPLES::
292
293
sage: from sage.functions.wigner import _big_delta_coeff
294
sage: _big_delta_coeff(1,1,1)
295
1/2*sqrt(1/6)
296
"""
297
if int(aa + bb - cc) != (aa + bb - cc):
298
raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
299
if int(aa + cc - bb) != (aa + cc - bb):
300
raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
301
if int(bb + cc - aa) != (bb + cc - aa):
302
raise ValueError("j values must be integer or half integer and fulfill the triangle relation")
303
if (aa + bb - cc) < 0:
304
return 0
305
if (aa + cc - bb) < 0:
306
return 0
307
if (bb + cc - aa) < 0:
308
return 0
309
310
maxfact = max(aa + bb - cc, aa + cc - bb, bb + cc - aa, aa + bb + cc + 1)
311
_calc_factlist(maxfact)
312
313
argsqrt = Integer(_Factlist[int(aa + bb - cc)] * \
314
_Factlist[int(aa + cc - bb)] * \
315
_Factlist[int(bb + cc - aa)]) / \
316
Integer(_Factlist[int(aa + bb + cc + 1)])
317
318
ressqrt = argsqrt.sqrt(prec)
319
if type(ressqrt) is ComplexNumber:
320
res = ressqrt.real()
321
else:
322
res = ressqrt
323
return res
324
325
326
def racah(aa, bb, cc, dd, ee, ff, prec=None):
327
r"""
328
Calculate the Racah symbol `W(a,b,c,d;e,f)`.
329
330
INPUT:
331
332
- ``a``, ..., ``f`` - integer or half integer
333
334
- ``prec`` - precision, default: ``None``. Providing a precision can
335
drastically speed up the calculation.
336
337
OUTPUT:
338
339
Rational number times the square root of a rational number
340
(if ``prec=None``), or real number if a precision is given.
341
342
EXAMPLES::
343
344
sage: racah(3,3,3,3,3,3)
345
-1/14
346
347
NOTES:
348
349
The Racah symbol is related to the Wigner 6j symbol:
350
351
.. math::
352
353
Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6)
354
=(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
355
356
Please see the 6j symbol for its much richer symmetries and for
357
additional properties.
358
359
ALGORITHM:
360
361
This function uses the algorithm of [Edmonds74]_ to calculate the
362
value of the 6j symbol exactly. Note that the formula contains
363
alternating sums over large factorials and is therefore unsuitable
364
for finite precision arithmetic and only useful for a computer
365
algebra system [Rasch03]_.
366
367
AUTHORS:
368
369
- Jens Rasch (2009-03-24): initial version
370
"""
371
prefac = _big_delta_coeff(aa, bb, ee, prec) * \
372
_big_delta_coeff(cc, dd, ee, prec) * \
373
_big_delta_coeff(aa, cc, ff, prec) * \
374
_big_delta_coeff(bb, dd, ff, prec)
375
if prefac == 0:
376
return 0
377
imin = max(aa + bb + ee, cc + dd + ee, aa + cc + ff, bb + dd + ff)
378
imax = min(aa + bb + cc + dd, aa + dd + ee + ff, bb + cc + ee + ff)
379
380
maxfact = max(imax + 1, aa + bb + cc + dd, aa + dd + ee + ff, \
381
bb + cc + ee + ff)
382
_calc_factlist(maxfact)
383
384
sumres = 0
385
for kk in range(imin, imax + 1):
386
den = _Factlist[int(kk - aa - bb - ee)] * \
387
_Factlist[int(kk - cc - dd - ee)] * \
388
_Factlist[int(kk - aa - cc - ff)] * \
389
_Factlist[int(kk - bb - dd - ff)] * \
390
_Factlist[int(aa + bb + cc + dd - kk)] * \
391
_Factlist[int(aa + dd + ee + ff - kk)] * \
392
_Factlist[int(bb + cc + ee + ff - kk)]
393
sumres = sumres + Integer((-1) ** kk * _Factlist[kk + 1]) / den
394
395
res = prefac * sumres * (-1) ** int(aa + bb + cc + dd)
396
return res
397
398
399
def wigner_6j(j_1, j_2, j_3, j_4, j_5, j_6, prec=None):
400
r"""
401
Calculate the Wigner 6j symbol `Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6)`.
402
403
INPUT:
404
405
- ``j_1``, ..., ``j_6`` - integer or half integer
406
407
- ``prec`` - precision, default: ``None``. Providing a precision can
408
drastically speed up the calculation.
409
410
OUTPUT:
411
412
Rational number times the square root of a rational number
413
(if ``prec=None``), or real number if a precision is given.
414
415
EXAMPLES::
416
417
sage: wigner_6j(3,3,3,3,3,3)
418
-1/14
419
sage: wigner_6j(5,5,5,5,5,5)
420
1/52
421
sage: wigner_6j(6,6,6,6,6,6)
422
309/10868
423
sage: wigner_6j(8,8,8,8,8,8)
424
-12219/965770
425
sage: wigner_6j(30,30,30,30,30,30)
426
36082186869033479581/87954851694828981714124
427
sage: wigner_6j(0.5,0.5,1,0.5,0.5,1)
428
1/6
429
sage: wigner_6j(200,200,200,200,200,200, prec=1000)*1.0
430
0.000155903212413242
431
432
It is an error to have arguments that are not integer or half
433
integer values or do not fulfill the triangle relation::
434
435
sage: wigner_6j(2.5,2.5,2.5,2.5,2.5,2.5)
436
Traceback (most recent call last):
437
...
438
ValueError: j values must be integer or half integer and fulfill the triangle relation
439
sage: wigner_6j(0.5,0.5,1.1,0.5,0.5,1.1)
440
Traceback (most recent call last):
441
...
442
ValueError: j values must be integer or half integer and fulfill the triangle relation
443
444
NOTES:
445
446
The Wigner 6j symbol is related to the Racah symbol but exhibits
447
more symmetries as detailed below.
448
449
.. math::
450
451
Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6)
452
=(-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6)
453
454
The Wigner 6j symbol obeys the following symmetry rules:
455
456
- Wigner 6j symbols are left invariant under any permutation of
457
the columns:
458
459
.. math::
460
461
Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6)
462
=Wigner6j(j_3,j_1,j_2,j_6,j_4,j_5)
463
=Wigner6j(j_2,j_3,j_1,j_5,j_6,j_4)
464
=Wigner6j(j_3,j_2,j_1,j_6,j_5,j_4)
465
=Wigner6j(j_1,j_3,j_2,j_4,j_6,j_5)
466
=Wigner6j(j_2,j_1,j_3,j_5,j_4,j_6)
467
468
- They are invariant under the exchange of the upper and lower
469
arguments in each of any two columns, i.e.
470
471
.. math::
472
473
Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6)
474
=Wigner6j(j_1,j_5,j_6,j_4,j_2,j_3)
475
=Wigner6j(j_4,j_2,j_6,j_1,j_5,j_3)
476
=Wigner6j(j_4,j_5,j_3,j_1,j_2,j_6)
477
478
- additional 6 symmetries [Regge59]_ giving rise to 144 symmetries
479
in total
480
481
- only non-zero if any triple of `j`'s fulfill a triangle relation
482
483
ALGORITHM:
484
485
This function uses the algorithm of [Edmonds74]_ to calculate the
486
value of the 6j symbol exactly. Note that the formula contains
487
alternating sums over large factorials and is therefore unsuitable
488
for finite precision arithmetic and only useful for a computer
489
algebra system [Rasch03]_.
490
491
REFERENCES:
492
493
.. [Regge59] 'Symmetry Properties of Racah Coefficients',
494
T. Regge, Nuovo Cimento, Volume 11, pp. 116 (1959)
495
"""
496
res = (-1) ** int(j_1 + j_2 + j_4 + j_5) * \
497
racah(j_1, j_2, j_5, j_4, j_3, j_6, prec)
498
return res
499
500
501
def wigner_9j(j_1, j_2, j_3, j_4, j_5, j_6, j_7, j_8, j_9, prec=None):
502
r"""
503
Calculate the Wigner 9j symbol
504
`Wigner9j(j_1,j_2,j_3,j_4,j_5,j_6,j_7,j_8,j_9)`.
505
506
INPUT:
507
508
- ``j_1``, ..., ``j_9`` - integer or half integer
509
510
- ``prec`` - precision, default: ``None``. Providing a precision can
511
drastically speed up the calculation.
512
513
OUTPUT:
514
515
Rational number times the square root of a rational number
516
(if ``prec=None``), or real number if a precision is given.
517
518
EXAMPLES:
519
520
A couple of examples and test cases, note that for speed reasons a
521
precision is given::
522
523
sage: wigner_9j(1,1,1, 1,1,1, 1,1,0 ,prec=64) # ==1/18
524
0.0555555555555555555
525
sage: wigner_9j(1,1,1, 1,1,1, 1,1,1)
526
0
527
sage: wigner_9j(1,1,1, 1,1,1, 1,1,2 ,prec=64) # ==1/18
528
0.0555555555555555556
529
sage: wigner_9j(1,2,1, 2,2,2, 1,2,1 ,prec=64) # ==-1/150
530
-0.00666666666666666667
531
sage: wigner_9j(3,3,2, 2,2,2, 3,3,2 ,prec=64) # ==157/14700
532
0.0106802721088435374
533
sage: wigner_9j(3,3,2, 3,3,2, 3,3,2 ,prec=64) # ==3221*sqrt(70)/(246960*sqrt(105)) - 365/(3528*sqrt(70)*sqrt(105))
534
0.00944247746651111739
535
sage: wigner_9j(3,3,1, 3.5,3.5,2, 3.5,3.5,1 ,prec=64) # ==3221*sqrt(70)/(246960*sqrt(105)) - 365/(3528*sqrt(70)*sqrt(105))
536
0.0110216678544351364
537
sage: wigner_9j(100,80,50, 50,100,70, 60,50,100 ,prec=1000)*1.0
538
1.05597798065761e-7
539
sage: wigner_9j(30,30,10, 30.5,30.5,20, 30.5,30.5,10 ,prec=1000)*1.0 # ==(80944680186359968990/95103769817469)*sqrt(1/682288158959699477295)
540
0.0000325841699408828
541
sage: wigner_9j(64,62.5,114.5, 61.5,61,112.5, 113.5,110.5,60, prec=1000)*1.0
542
-3.41407910055520e-39
543
sage: wigner_9j(15,15,15, 15,3,15, 15,18,10, prec=1000)*1.0
544
-0.0000778324615309539
545
sage: wigner_9j(1.5,1,1.5, 1,1,1, 1.5,1,1.5)
546
0
547
548
It is an error to have arguments that are not integer or half
549
integer values or do not fulfill the triangle relation::
550
551
sage: wigner_9j(0.5,0.5,0.5, 0.5,0.5,0.5, 0.5,0.5,0.5,prec=64)
552
Traceback (most recent call last):
553
...
554
ValueError: j values must be integer or half integer and fulfill the triangle relation
555
sage: wigner_9j(1,1,1, 0.5,1,1.5, 0.5,1,2.5,prec=64)
556
Traceback (most recent call last):
557
...
558
ValueError: j values must be integer or half integer and fulfill the triangle relation
559
560
ALGORITHM:
561
562
This function uses the algorithm of [Edmonds74]_ to calculate the
563
value of the 3j symbol exactly. Note that the formula contains
564
alternating sums over large factorials and is therefore unsuitable
565
for finite precision arithmetic and only useful for a computer
566
algebra system [Rasch03]_.
567
"""
568
imin = 0
569
imax = min(j_1 + j_9, j_2 + j_6, j_4 + j_8)
570
571
sumres = 0
572
for kk in range(imin, imax + 1):
573
sumres = sumres + (2 * kk + 1) * \
574
racah(j_1, j_2, j_9, j_6, j_3, kk, prec) * \
575
racah(j_4, j_6, j_8, j_2, j_5, kk, prec) * \
576
racah(j_1, j_4, j_9, j_8, j_7, kk, prec)
577
return sumres
578
579
580
def gaunt(l_1, l_2, l_3, m_1, m_2, m_3, prec=None):
581
r"""
582
Calculate the Gaunt coefficient.
583
584
The Gaunt coefficient is defined as the integral over three
585
spherical harmonics:
586
587
.. math::
588
589
Y(j_1,j_2,j_3,m_1,m_2,m_3)
590
=\int Y_{l_1,m_1}(\Omega)
591
Y_{l_2,m_2}(\Omega) Y_{l_3,m_3}(\Omega) d\Omega
592
=\sqrt{(2l_1+1)(2l_2+1)(2l_3+1)/(4\pi)}
593
\; Y(j_1,j_2,j_3,0,0,0) \; Y(j_1,j_2,j_3,m_1,m_2,m_3)
594
595
INPUT:
596
597
- ``l_1``, ``l_2``, ``l_3``, ``m_1``, ``m_2``, ``m_3`` - integer
598
599
- ``prec`` - precision, default: ``None``. Providing a precision can
600
drastically speed up the calculation.
601
602
OUTPUT:
603
604
Rational number times the square root of a rational number
605
(if ``prec=None``), or real number if a precision is given.
606
607
EXAMPLES::
608
609
sage: gaunt(1,0,1,1,0,-1)
610
-1/2/sqrt(pi)
611
sage: gaunt(1,0,1,1,0,0)
612
0
613
sage: gaunt(29,29,34,10,-5,-5)
614
1821867940156/215552371055153321*sqrt(22134)/sqrt(pi)
615
sage: gaunt(20,20,40,1,-1,0)
616
28384503878959800/74029560764440771/sqrt(pi)
617
sage: gaunt(12,15,5,2,3,-5)
618
91/124062*sqrt(36890)/sqrt(pi)
619
sage: gaunt(10,10,12,9,3,-12)
620
-98/62031*sqrt(6279)/sqrt(pi)
621
sage: gaunt(1000,1000,1200,9,3,-12).n(64)
622
0.00689500421922113448
623
624
It is an error to use non-integer values for `l` and `m`::
625
626
sage: gaunt(1.2,0,1.2,0,0,0)
627
Traceback (most recent call last):
628
...
629
ValueError: l values must be integer
630
sage: gaunt(1,0,1,1.1,0,-1.1)
631
Traceback (most recent call last):
632
...
633
ValueError: m values must be integer
634
635
NOTES:
636
637
The Gaunt coefficient obeys the following symmetry rules:
638
639
- invariant under any permutation of the columns
640
641
.. math::
642
Y(j_1,j_2,j_3,m_1,m_2,m_3)
643
=Y(j_3,j_1,j_2,m_3,m_1,m_2)
644
=Y(j_2,j_3,j_1,m_2,m_3,m_1)
645
=Y(j_3,j_2,j_1,m_3,m_2,m_1)
646
=Y(j_1,j_3,j_2,m_1,m_3,m_2)
647
=Y(j_2,j_1,j_3,m_2,m_1,m_3)
648
649
- invariant under space inflection, i.e.
650
651
.. math::
652
Y(j_1,j_2,j_3,m_1,m_2,m_3)
653
=Y(j_1,j_2,j_3,-m_1,-m_2,-m_3)
654
655
- symmetric with respect to the 72 Regge symmetries as inherited
656
for the `3j` symbols [Regge58]_
657
658
- zero for `l_1`, `l_2`, `l_3` not fulfilling triangle relation
659
660
- zero for violating any one of the conditions: `l_1 \ge |m_1|`,
661
`l_2 \ge |m_2|`, `l_3 \ge |m_3|`
662
663
- non-zero only for an even sum of the `l_i`, i.e.
664
`J=l_1+l_2+l_3=2n` for `n` in `\Bold{N}`
665
666
ALGORITHM:
667
668
This function uses the algorithm of [Liberatodebrito82]_ to
669
calculate the value of the Gaunt coefficient exactly. Note that
670
the formula contains alternating sums over large factorials and is
671
therefore unsuitable for finite precision arithmetic and only
672
useful for a computer algebra system [Rasch03]_.
673
674
REFERENCES:
675
676
.. [Liberatodebrito82] 'FORTRAN program for the integral of three
677
spherical harmonics', A. Liberato de Brito,
678
Comput. Phys. Commun., Volume 25, pp. 81-85 (1982)
679
680
AUTHORS:
681
682
- Jens Rasch (2009-03-24): initial version for Sage
683
"""
684
if int(l_1) != l_1 or int(l_2) != l_2 or int(l_3) != l_3:
685
raise ValueError("l values must be integer")
686
if int(m_1) != m_1 or int(m_2) != m_2 or int(m_3) != m_3:
687
raise ValueError("m values must be integer")
688
689
bigL = (l_1 + l_2 + l_3) / 2
690
a1 = l_1 + l_2 - l_3
691
if a1 < 0:
692
return 0
693
a2 = l_1 - l_2 + l_3
694
if a2 < 0:
695
return 0
696
a3 = -l_1 + l_2 + l_3
697
if a3 < 0:
698
return 0
699
if Mod(2 * bigL, 2) != 0:
700
return 0
701
if (m_1 + m_2 + m_3) != 0:
702
return 0
703
if (abs(m_1) > l_1) or (abs(m_2) > l_2) or (abs(m_3) > l_3):
704
return 0
705
706
imin = max(-l_3 + l_1 + m_2, -l_3 + l_2 - m_1, 0)
707
imax = min(l_2 + m_2, l_1 - m_1, l_1 + l_2 - l_3)
708
709
maxfact = max(l_1 + l_2 + l_3 + 1, imax + 1)
710
_calc_factlist(maxfact)
711
712
argsqrt = (2 * l_1 + 1) * (2 * l_2 + 1) * (2 * l_3 + 1) * \
713
_Factlist[l_1 - m_1] * _Factlist[l_1 + m_1] * _Factlist[l_2 - m_2] * \
714
_Factlist[l_2 + m_2] * _Factlist[l_3 - m_3] * _Factlist[l_3 + m_3] / \
715
(4*pi)
716
ressqrt = argsqrt.sqrt()
717
718
prefac = Integer(_Factlist[bigL] * _Factlist[l_2 - l_1 + l_3] * \
719
_Factlist[l_1 - l_2 + l_3] * _Factlist[l_1 + l_2 - l_3])/ \
720
_Factlist[2 * bigL+1]/ \
721
(_Factlist[bigL - l_1] * _Factlist[bigL - l_2] * _Factlist[bigL - l_3])
722
723
sumres = 0
724
for ii in range(imin, imax + 1):
725
den = _Factlist[ii] * _Factlist[ii + l_3 - l_1 - m_2] * \
726
_Factlist[l_2 + m_2 - ii] * _Factlist[l_1 - ii - m_1] * \
727
_Factlist[ii + l_3 - l_2 + m_1] * _Factlist[l_1 + l_2 - l_3 - ii]
728
sumres = sumres + Integer((-1) ** ii) / den
729
730
res = ressqrt * prefac * sumres * (-1) ** (bigL + l_3 + m_1 - m_2)
731
if prec != None:
732
res = res.n(prec)
733
return res
734
735