Ok, here it is: ----------------------------------------------------------------------------------------------- r""" Calculate Wigner 3j, 6j, 9j, Clebsch-Gordan, Racah and Gaunt coefficients
Collection of functions for calculating er 3j, 6j, 9j, Clebsch-Gordan, Racah as well as Gaunt coefficients exactly, all evaluating to a rational number times the square root of a rational number [Rasch03]. Please see the description of the individual functions for further details and examples. REFERENCES: - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) AUTHORS: - Jens Rasch (2009-03-24): initial version for Sage """ #*********************************************************************** # Copyright (C) 2008 Jens Rasch <jyr2...@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ #*********************************************************************** from sage.all import * # from sage.calculus.calculus import sqrt,factorial # from sage.functions.constants import pi # This list of precomputed factorials is needed to massively # accelerate consequetive calculations of the various coefficients _Factlist=[1] def _calc_factlist(nn): if nn>=len(_Factlist): for ii in range(len(_Factlist),nn+1): _Factlist.append(_Factlist[ii-1]*ii) #_Factlist.append(factorial(ii)) #return _Factlist def test_calc_factlist(nn): r""" Function calculates a list of precomputed factorials in order to massively accelerate consequetive calculations of the various coefficients. INPUT: - nn Highest factorial to be computed OUTPUT: integer list of factorials EXAMPLES: Calculate list of factorials: sage: test_calc_factlist(10) [1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800] """ _calc_factlist(nn) return _Factlist def Wigner3j(j_1,j_2,j_3,m_1,m_2,m_3,prec=None): r""" Calculate the Wigner 3j symbol \left({j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop m_3} \right) NOTES: The Wigner 3j symbol obeys the following symmetry rules: - invariant under any permutation of the columns (with the exception of a sign change where $J:=j_1+j_2+j_3$): \begin{eqnarray} \left({j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop m_3}\right) &=& \left({j_3 \atop m_3} {j_1 \atop m_1} {j_2 \atop m_2}\right) =\left({j_2 \atop m_2} {j_3 \atop m_3} {j_1 \atop m_1}\right) \qquad \mbox{cyclic} &=& (-)^{J}\left({j_3\atop m_3} {j_2\atop m_2} {j_1\atop m_1}\right) =(-)^{J}\left({j_1\atop m_1} {j_3\atop m_3} {j_2\atop m_2}\right) =(-)^{J}\left({j_2\atop m_2} {j_1\atop m_1} {j_3\atop m_3}\right) \qquad\mbox{anti-cyclic} \end{eqnarray} - invariant under space inflection, i. e. \begin{eqnarray} \left({{j_1}\atop{m_1}} {{j_2}\atop{m_2}} {{j_3}\atop{m_3}} \right) = (-)^{J} \left({j_1 \atop -m_1} {j_2 \atop -m_2}{j_3 \atop -m_3}\right) \end{eqnarray} - symmetric with respect to the 72 additional symmetries based on the work by [Regge58] - zero for $j_1$, $j_2$, $j_3$ not fulfilling triangle relation - zero for ${m_1}+{m_2}+{m_3}!= 0$ - zero for violating any one of the conditions $j_1\ge|m_1|$, $j_2\ge|m_2|$, $j_3\ge|m_3|$ ALGORITHM: This function uses the algorithm of [Edmonds74] to calculate the value of the 3j symbol exactly. Note that the formula contains alternating sums over large factorials and is therefore unsuitable for finite precision arithmetic and only useful for a computer algebra system [Rasch03]. INPUT: j_1 - integer or half integer j_2 - integer or half integer j_3 - integer or half integer m_1 - integer or half integer m_2 - integer or half integer m_3 - integer or half integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: A couple of examples: sage: Wigner3j(2,6,4,0,0,0) sqrt(5)/sqrt(143) sage: Wigner3j(2,6,4,0,0,1) 0 sage: Wigner3j(0.5,0.5,1,0.5,-0.5,0) 1/sqrt(6) sage: Wigner3j(40,100,60,-10,60,-50) 95608*sqrt(21082735836735314343364163310)/(18702538494885*sqrt (220491455010479533763)) sage: Wigner3j(2500,2500,5000,2488,2400,-4888 ,prec=64) 7.60424456883448589e-12 It is an error to have arguments that are not integer or half integer values: sage: Wigner3j(2.1,6,4,0,0,0) Traceback (most recent call last): ... ValueError: j values must be integer or half integer sage: Wigner3j(2,6,4,1,0,-1.1) Traceback (most recent call last): ... ValueError: m values must be integer or half integer REFERENCES: - [Regge58] 'Symmetry Properties of Clebsch-Gordan Coefficients', T. Regge, Nuovo Cimento, Volume 10, pp. 544 (1958) - [Edmonds74] 'Angular Momentum in Quantum Mechanics', A. R. Edmonds, Princeton University Press (1974) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) AUTHORS: - Jens Rasch (2009-03-24): initial version """ if int(j_1*2)!=j_1*2 or int(j_2*2)!=j_2*2 or int(j_3*2)!=j_3*2: raise ValueError("j values must be integer or half integer") #return 0 if int(m_1*2)!=m_1*2 or int(m_2*2)!=m_2*2 or int(m_3*2)!=m_3*2: raise ValueError("m values must be integer or half integer") #return 0 if (m_1+m_2+m_3<>0): return 0 prefid=Integer((-1)**(int(j_1-j_2-m_3))) m_3=-m_3 a1=j_1+j_2-j_3 if (a1<0): return 0 a2=j_1-j_2+j_3 if (a2<0): return 0 a3=-j_1+j_2+j_3 if (a3<0): return 0 if (abs(m_1)>j_1) or (abs(m_2)>j_2) or (abs(m_3)>j_3): return 0 maxfact=max(j_1+j_2+j_3+1,j_1+abs(m_1),j_2+abs(m_2),j_3+abs(m_3)) _calc_factlist(maxfact) #try: argsqrt=Integer(_Factlist[int(j_1+j_2-j_3)]\ *_Factlist[int(j_1-j_2+j_3)]\ *_Factlist[int(-j_1+j_2+j_3)]\ *_Factlist[int(j_1-m_1)]*_Factlist[int(j_1+m_1)]\ *_Factlist[int(j_2-m_2)]*_Factlist[int(j_2+m_2)]\ *_Factlist[int(j_3-m_3)]*_Factlist[j_3+m_3])\ /_Factlist[int(j_1+j_2+j_3+1)]\ #except: # return 0 ressqrt=sqrt(argsqrt,prec) if type(ressqrt)==sage.rings.complex_number.ComplexNumber: ressqrt=ressqrt.real() imin=max(-j_3+j_1+m_2,-j_3+j_2-m_1,0) imax=min(j_2+m_2,j_1-m_1,j_1+j_2-j_3) sumres=0 for ii in range(imin,imax+1): den=_Factlist[ii]*_Factlist[int(ii+j_3-j_1-m_2)]\ *_Factlist[int(j_2+m_2-ii)]*_Factlist[int(j_1-ii-m_1)]\ *_Factlist[int(ii+j_3-j_2+m_1)]\ *_Factlist[int(j_1+j_2-j_3-ii)] sumres=sumres+Integer((-1)**ii)/den res=ressqrt*sumres*prefid return res def ClebschGordan(j_1,j_2,j_3,m_1,m_2,m_3,prec=None): r""" Calculates the Clebsch-Gordan coefficient $\left< j_1 m_1 \; j_2 m_2 | j_3 m_3 \right>$ NOTES: The Clebsch-Gordan coefficient will be evaluated via its relation to Wigner 3j symbols: \begin{eqnarray} \left< j_1 m_1 \; j_2 m_2 | j_3 m_3 \right>= (-1)^(j_1-j_2+m_3) \sqrt(2j_3+1) \left({j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop -m_3}\right) \end{eqnarray} See also the documentation on Wigner 3j symbols which exhibit much higher symmetry releations that the Clebsch-Gordan coefficient. INPUT: j_1 - integer or half integer j_2 - integer or half integer j_3 - integer or half integer m_1 - integer or half integer m_2 - integer or half integer m_3 - integer or half integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: A couple of examples: sage: ClebschGordan(3/2,1/2,2, 3/2,1/2,2) 1 sage: ClebschGordan(1.5,0.5,1, 1.5,-0.5,1) sqrt(3)/2 sage: ClebschGordan(3/2,1/2,1, -1/2,1/2,0) -sqrt(3)/sqrt(6) REFERENCES: - [Edmonds74] 'Angular Momentum in Quantum Mechanics', A. R. Edmonds, Princeton University Press (1974) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) AUTHORS: - Jens Rasch (2009-03-24): initial version """ res=(-1)**(int(j_1-j_2+m_3))*sqrt(2*j_3+1)\ *Wigner3j(j_1,j_2,j_3,m_1,m_2,-m_3,prec) return res def _bigDeltacoeff(aa,bb,cc,prec=None): r""" Calculates the Delta coefficient of the 3 angular momenta for Racah symbols. Also checks that the differences are of integer value. INPUT: - aa - first angular momentum, integer or half integer - bb - second angular momentum, integer or half integer - cc - third angular momentum, integer or half integer - prec - precission of the sqrt() calculation OUTPUT: double - Value of the Delta coefficient """ if(int(aa+bb-cc)!=(aa+bb-cc)): raise ValueError("j values must be integer or half integer and fullfil the triangle relation") #return 0 if(int(aa+cc-bb)!=(aa+cc-bb)): raise ValueError("j values must be integer or half integer and fullfil the triangle relation") #return 0 if(int(bb+cc-aa)!=(bb+cc-aa)): raise ValueError("j values must be integer or half integer and fullfil the triangle relation") #return 0 if(aa+bb-cc)<0: return 0 if(aa+cc-bb)<0: return 0 if(bb+cc-aa)<0: return 0 maxfact=max(aa+bb-cc,aa+cc-bb,bb+cc-aa,aa+bb+cc+1) _calc_factlist(maxfact) argsqrt=Integer(_Factlist[int(aa+bb-cc)]*_Factlist[int(aa+cc-bb)]\ *_Factlist[int(bb+cc-aa)])\ /Integer(_Factlist[int(aa+bb+cc+1)]) ressqrt=sqrt(argsqrt,prec) if type(ressqrt)==sage.rings.complex_number.ComplexNumber: res=ressqrt.real() else: res=ressqrt return res def test_bigDeltacoeff(aa,bb,cc,prec=None): r""" Test for the Delta coefficient of the 3 angular momenta for Racah symbols. Also checks that the differences are of integer value. INPUT: - aa - first angular momentum, integer or half integer - bb - second angular momentum, integer or half integer - cc - third angular momentum, integer or half integer - prec - precission of the sqrt() calculation OUTPUT: double - Value of the Delta coefficient EXAMPLES: Simple examples: sage: test_bigDeltacoeff(1,1,1) 1/(2*sqrt(6)) """ return _bigDeltacoeff(aa,bb,cc,prec) def Racah(aa,bb,cc,dd,ee,ff,prec=None): r""" Calculate the Racah symbol W(a,b,c,d;e,f) NOTES: The Racah symbol is related to the Wigner 6j symbol: \begin{eqnarray} \left({j_1 \atop j_4} {j_2 \atop j_5} {j_3 \atop j_6} \right) = (-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6) \end{eqnarray} Please see the 6j symbol for its much richer symmetries and for additional properties. ALGORITHM: This function uses the algorithm of [Edmonds74] to calculate the value of the 6j symbol exactly. Note that the formula contains alternating sums over large factorials and is therefore unsuitable for finite precision arithmetic and only useful for a computer algebra system [Rasch03]. INPUT: a - integer or half integer b - integer or half integer c - integer or half integer d - integer or half integer e - integer or half integer f - integer or half integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: A couple of examples and testcases: sage: Racah(3,3,3,3,3,3) -1/14 REFERENCES: - [Edmonds74] 'Angular Momentum in Quantum Mechanics', A. R. Edmonds, Princeton University Press (1974) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) AUTHORS: - Jens Rasch (2009-03-24): initial version """ prefac=_bigDeltacoeff(aa,bb,ee,prec)*_bigDeltacoeff(cc,dd,ee,prec) \ *_bigDeltacoeff(aa,cc,ff,prec)*_bigDeltacoeff (bb,dd,ff,prec) if prefac==0: return 0 imin=max(aa+bb+ee,cc+dd+ee,aa+cc+ff,bb+dd+ff) imax=min(aa+bb+cc+dd,aa+dd+ee+ff,bb+cc+ee+ff) maxfact=max(imax+1,aa+bb+cc+dd,aa+dd+ee+ff,bb+cc+ee+ff) _calc_factlist(maxfact) sumres=0 for kk in range(imin,imax+1): den=_Factlist[int(kk-aa-bb-ee)]*_Factlist[int(kk-cc-dd-ee)]\ *_Factlist[int(kk-aa-cc-ff)]\ *_Factlist[int(kk-bb-dd-ff)]*_Factlist[int(aa+bb+cc+dd-kk)] \ *_Factlist[int(aa+dd+ee+ff-kk)]\ *_Factlist[int(bb+cc+ee+ff-kk)] sumres=sumres+Integer((-1)**kk*_Factlist[kk+1])/den res=prefac*sumres*(-1)**(int(aa+bb+cc+dd)) return res def Wigner6j(j_1,j_2,j_3,j_4,j_5,j_6,prec=None): r""" Calculate the Wigner 6j symbol \left({j_1 \atop j_4} {j_2 \atop j_5} {j_3 \atop j_6} \right) NOTES: The Wigner 6j symbol is related to the Racah symbol but exhibits more symmetries as detailed below. \begin{eqnarray} \left({j_1 \atop j_4} {j_2 \atop j_5} {j_3 \atop j_6} \right) = (-1)^{j_1+j_2+j_4+j_5} W(j_1,j_2,j_5,j_4,j_3,j_6) \end{eqnarray} The Wigner 6j symbol obeys the following symmetry rules: - Wigner $6j$ symbols are left invariant under any permutation of the columns: \begin{eqnarray} \left({j_1 \atop j_4} {j_2 \atop j_5} {j_3 \atop j_6} \right) &=& \left({j_3 \atop j_6} {j_1 \atop j_4} {j_2 \atop j_5} \right) =\left({j_2 \atop j_5} {j_3 \atop j_6} {j_2 \atop j_4} \right) \qquad \mbox{cyclic} \\ &=& \left({j_3 \atop j_6} {j_2 \atop j_5} {j_1 \atop j_4} \right) =\left({j_1 \atop j_4} {j_3 \atop j_6} {j_2 \atop j_5} \right) =\left({j_2 \atop j_5} {j_1 \atop j_4} {j_3 \atop j_6} \right) \qquad \mbox{anti-cyclic} \end{eqnarray} - They are invariant under the exchange of the upper and lower arguments in each of any two columns, i. e. \begin{eqnarray} \left({j_1 \atop j_4} {j_2 \atop j_5} {j_3 \atop j_6} \right) = \left({j_1 \atop j_4} {j_5 \atop j_2} {j_6 \atop j_3} \right) = \left({j_4 \atop j_1} {j_2 \atop j_5} {j_6 \atop j_3} \right) = \left({j_4 \atop j_1} {j_5 \atop j_2} {j_3 \atop j_6} \right) \end{eqnarray} - additional 6 symmetries [Regge59] giving rise to 144 symmetries in total - only non-zero if any triple of $j$'s fulfil a triangle relation ALGORITHM: This function uses the algorithm of [Edmonds74] to calculate the value of the 6j symbol exactly. Note that the formula contains alternating sums over large factorials and is therefore unsuitable for finite precision arithmetic and only useful for a computer algebra system [Rasch03]. INPUT: j_1 - integer or half integer j_2 - integer or half integer j_3 - integer or half integer j_4 - integer or half integer j_5 - integer or half integer j_6 - integer or half integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: A couple of examples and testcases: sage: Wigner6j(3,3,3,3,3,3) -1/14 sage: Wigner6j(5,5,5,5,5,5) 1/52 sage: Wigner6j(6,6,6,6,6,6) 309/10868 sage: Wigner6j(8,8,8,8,8,8) -12219/965770 sage: Wigner6j(30,30,30,30,30,30) 36082186869033479581/87954851694828981714124 sage: Wigner6j(0.5,0.5,1,0.5,0.5,1) 1/6 sage: Wigner6j(200,200,200,200,200,200, prec=1000)*1.0 0.000155903212413242 It is an error to have arguments that are not integer or half integer values or do not fulfill the triangle relation: sage: Wigner6j(2.5,2.5,2.5,2.5,2.5,2.5) Traceback (most recent call last): ... ValueError: j values must be integer or half integer and fullfil the triangle relation sage: Wigner6j(0.5,0.5,1.1,0.5,0.5,1.1) Traceback (most recent call last): ... ValueError: j values must be integer or half integer and fullfil the triangle relation REFERENCES: - [Regge59] 'Symmetry Properties of Racah Coefficients', T. Regge, Nuovo Cimento, Volume 11, pp. 116 (1959) - [Edmonds74] 'Angular Momentum in Quantum Mechanics', A. R. Edmonds, Princeton University Press (1974) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) """ res=(-1)**(int(j_1+j_2+j_4+j_5))*Racah (j_1,j_2,j_5,j_4,j_3,j_6,prec) return res def Wigner9j(j_1,j_2,j_3,j_4,j_5,j_6,j_7,j_8,j_9,prec=None): r""" Calculate the Wigner 9j symbol \left\{ \begin{matrix} {j_1} & {j_2} & {j_3} \\ {j_4} & {j_5} & {j_6} \\ {j_7} & {j_8} & {j_9} \end{matrix} \right\} ALGORITHM: This function uses the algorithm of [Edmonds74] to calculate the value of the 3j symbol exactly. Note that the formula contains alternating sums over large factorials and is therefore unsuitable for finite precision arithmetic and only useful for a computer algebra system [Rasch03]. INPUT: j_1 - integer or half integer j_2 - integer or half integer j_3 - integer or half integer j_4 - integer or half integer j_5 - integer or half integer j_6 - integer or half integer j_7 - integer or half integer j_8 - integer or half integer j_9 - integer or half integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: A couple of examples and testcases, note that for speed reasons a precission is given: sage: Wigner9j(1,1,1, 1,1,1, 1,1,0 ,prec=64) # ==1/18 0.0555555555555555555 sage: Wigner9j(1,1,1, 1,1,1, 1,1,1) 0 sage: Wigner9j(1,1,1, 1,1,1, 1,1,2 ,prec=64) # ==1/18 0.0555555555555555556 sage: Wigner9j(1,2,1, 2,2,2, 1,2,1 ,prec=64) # ==-1/150 -0.00666666666666666667 sage: Wigner9j(3,3,2, 2,2,2, 3,3,2 ,prec=64) # ==157/14700 0.0106802721088435374 sage: Wigner9j(3,3,2, 3,3,2, 3,3,2 ,prec=64) # ==3221*sqrt(70)/ (246960*sqrt(105)) - 365/(3528*sqrt(70)*sqrt(105)) 0.00944247746651111739 sage: Wigner9j(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)) 0.0110216678544351364 sage: Wigner9j(100,80,50, 50,100,70, 60,50,100 ,prec=1000)*1.0 1.05597798065761e-7 sage: Wigner9j(30,30,10, 30.5,30.5,20, 30.5,30.5,10 ,prec=1000) *1.0 # ==(80944680186359968990/95103769817469)*sqrt (1/682288158959699477295) 0.0000325841699408828 sage: Wigner9j(64,62.5,114.5, 61.5,61,112.5, 113.5,110.5,60, prec=1000)*1.0 -3.41407910055520e-39 sage: Wigner9j(15,15,15, 15,3,15, 15,18,10, prec=1000)*1.0 -0.0000778324615309539 sage: Wigner9j(1.5,1,1.5, 1,1,1, 1.5,1,1.5) 0 It is an error to have arguments that are not integer or half integer values or do not fulfill the triangle relation: sage: Wigner9j(0.5,0.5,0.5, 0.5,0.5,0.5, 0.5,0.5,0.5,prec=64) Traceback (most recent call last): ... ValueError: j values must be integer or half integer and fullfil the triangle relation sage: Wigner9j(1,1,1, 0.5,1,1.5, 0.5,1,2.5,prec=64) Traceback (most recent call last): ... ValueError: j values must be integer or half integer and fullfil the triangle relation REFERENCES: - [Edmonds74] 'Angular Momentum in Quantum Mechanics', A. R. Edmonds, Princeton University Press (1974) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) """ imin=0 imax=min(j_1+j_9,j_2+j_6,j_4+j_8) sumres=0 for kk in range(imin,imax+1): sumres=sumres+(2*kk+1)*Racah(j_1,j_2,j_9,j_6,j_3,kk,prec)\ *Racah(j_4,j_6,j_8,j_2,j_5,kk,prec)\ *Racah(j_1,j_4,j_9,j_8,j_7,kk,prec) return sumres def Gaunt(l_1,l_2,l_3,m_1,m_2,m_3,prec=None): r""" Calculate the Gaunt coefficient which is defined as the integral over three spherical harmonics: \begin{eqnarray} Y{j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop m_3} &=& \int Y_{l_1,m_1}(\Omega) Y_{l_2,m_2}(\Omega) Y_{l_3,m_3}(\Omega)\; d\Omega \\ &=& \sqrt{\frac{(2l_1+1)(2l_2+1)(2l_3+1)}{4\pi}} \left({l_1 \atop 0 } {l_2 \atop 0 } {l_3 \atop 0} \right) \left({l_1 \atop m_1} {l_2 \atop m_2} {l_3 \atop m_3} \right) \end{eqnarray} NOTES: The Gaunt coefficient obeys the following symmetry rules: - invariant under any permutation of the columns \begin{eqnarray} Y{j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop m_3} &=& Y{j_3 \atop m_3} {j_1 \atop m_1} {j_2 \atop m_2} =Y{j_2 \atop m_2} {j_3 \atop m_3} {j_1 \atop m_1} \qquad \mbox{cyclic} \\ &=& Y{j_3 \atop m_3} {j_2 \atop m_2} {j_1 \atop m_1} =Y{j_1 \atop m_1} {j_3 \atop m_3} {j_2 \atop m_2} =Y{j_2 \atop m_2} {j_1 \atop m_1} {j_3 \atop m_3} \qquad\mbox{anti-cyclic} \end{eqnarray} - invariant under space inflection, i.e. \begin{eqnarray} Y{j_1 \atop m_1} {j_2 \atop m_2} {j_3 \atop m_3} = Y{j_1 \atop -m_1} {j_2 \atop -m_2} {j_3 \atop -m_3} \end{eqnarray} - symmetric with respect to the 72 Regge symmetries as inherited for the $3j$ symbols [Regge58] - zero for $l_1$, $l_2$, $l_3$ not fulfilling triangle relation - zero for violating any one of the conditions: $l_1\ge|m_1|$, $l_2\ge|m_2|$, $l_3\ge|m_3| - non-zero only for an even sum of the $l_i$, i. e. $J=l_1+l_2+l_3=2n$ for $n$ in $\mathbf{N}$ ALGORITHM: This function uses the algorithm of [Liberatodebrito82] to calculate the value of the Gaunt coefficient exactly. Note that the formula contains alternating sums over large factorials and is therefore unsuitable for finite precision arithmetic and only useful for a computer algebra system [Rasch03]. INPUT: j_1 - integer j_2 - integer j_3 - integer m_1 - integer m_2 - integer m_3 - integer prec - precission, default: None. Providing a precission can drastically spead up the calculation. OUTPUT: The result will be a rational number times the square root of a rational number, unless a precission is given. EXAMPLES: sage: Gaunt(1,0,1,1,0,-1) -1/(2*sqrt(pi)) sage: Gaunt(1,0,1,1,0,0) 0 sage: Gaunt(29,29,34,10,-5,-5) 1821867940156*sqrt(22134)/(215552371055153321*sqrt(pi)) sage: Gaunt(20,20,40,1,-1,0) 28384503878959800/(74029560764440771*sqrt(pi)) sage: Gaunt(12,15,5,2,3,-5) 91*sqrt(36890)/(124062*sqrt(pi)) sage: Gaunt(10,10,12,9,3,-12) -98*sqrt(6279)/(62031*sqrt(pi)) sage: Gaunt(1000,1000,1200,9,3,-12).n(64) 0.00689500421922113448 It is an error to use non-integer values for $l$ and $m$: sage: Gaunt(1.2,0,1.2,0,0,0) Traceback (most recent call last): ... ValueError: l values must be integer sage: Gaunt(1,0,1,1.1,0,-1.1) Traceback (most recent call last): ... ValueError: m values must be integer REFERENCES: - [Regge58] 'Symmetry Properties of Clebsch-Gordan Coefficients', T. Regge, Nuovo Cimento, Volume 10, pp. 544 (1958) - [Liberatodebrito82] 'FORTRAN program for the integral of three spherical harmonics', A. Liberato de Brito, Comput. Phys. Commun., Volume 25, pp. 81-85 (1982) - [Rasch03] 'Efficient Storage Scheme for Precalculated Wigner 3j, 6j and Gaunt Coefficients', J. Rasch and A. C. H. Yu, SIAM J. Sci. Comput. Volume 25, Issue 4, pp. 1416-1428 (2003) AUTHORS: - Jens Rasch (2009-03-24): initial version for Sage """ if int(l_1)!=l_1 or int(l_2)!=l_2 or int(l_3)!=l_3: raise ValueError("l values must be integer") #return 0 if int(m_1)!=m_1 or int(m_2)!=m_2 or int(m_3)!=m_3: raise ValueError("m values must be integer") bigL=(l_1+l_2+l_3)/2 a1=l_1+l_2-l_3 if (a1<0): return 0 a2=l_1-l_2+l_3 if (a2<0): return 0 a3=-l_1+l_2+l_3 if (a3<0): return 0 if Mod(2*bigL,2)<>0: # if int(int(2*bigL)/2)<>int(bigL): return 0 if (m_1+m_2+m_3)<>0: return 0 if (abs(m_1)>l_1) or (abs(m_2)>l_2) or (abs(m_3)>l_3): return 0 imin=max(-l_3+l_1+m_2,-l_3+l_2-m_1,0) imax=min(l_2+m_2,l_1-m_1,l_1+l_2-l_3) maxfact=max(l_1+l_2+l_3+1,imax+1) _calc_factlist(maxfact) argsqrt=(2*l_1+1)*(2*l_2+1)*(2*l_3+1)*_Factlist[l_1-m_1]\ *_Factlist[l_1+m_1]*_Factlist[l_2-m_2]*_Factlist [l_2+m_2]\ *_Factlist[l_3-m_3]*_Factlist[l_3+m_3]/(4*pi) ressqrt=sqrt(argsqrt,prec) if type(ressqrt)==sage.rings.complex_number.ComplexNumber: ressqrt=ressqrt.real() prefac=Integer(_Factlist[bigL]*_Factlist[l_2-l_1+l_3]\ *_Factlist[l_1-l_2+l_3]\ *_Factlist[l_1+l_2-l_3])/_Factlist[2*bigL+1]\ /(_Factlist[bigL-l_1]*_Factlist[bigL-l_2]*_Factlist[bigL-l_3]) sumres=0 for ii in range(imin,imax+1): den=_Factlist[ii]*_Factlist[ii+l_3-l_1-m_2]\ *_Factlist[l_2+m_2-ii]*_Factlist[l_1-ii-m_1]\ *_Factlist[ii+l_3-l_2+m_1]*_Factlist[l_1+l_2-l_3-ii] sumres=sumres+Integer((-1)**ii)/den res=ressqrt*prefac*sumres*(-1)**(bigL+l_3+m_1-m_2) return res --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to sage-devel-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://www.sagemath.org -~----------~----~----~----~------~----~------~--~---