function [w6j,L,norma]=wigner6j(l2,l3,l4,l5,l6) % [w6j,L,norma]=WIGNER6J(l2,l3,l4,l5,l6) % % Calculates Wigner 6j symbols by recursion, for all values up to L % that are allowed in the expression (L l2 l3) % (l4 l5 l6) % There is no truncation at any bandwidth - they are all returned. % % INPUT: % % l2, l3, l4, l5, l6 The quantities defined above, all scalar % % OUTPUT: % % w6j The Wigner 6j symbols (with prepended zeroes) % L The degrees at which these are evaluated % norma Normalization check which passed muster % % EXAMPLES: % % wigner6j('demo1') % Just tests some values against Stone's code % wigner6j('demo2') % Reproduces Table IV and Figure 3 of Schulten and Gordon % wigner6j('demo3') % Reproduces Table III of Schulten and Gordon % wigner6j('demo4') % Reproduces Figure 4 of Schulten and Gordon % % COMPARE WITH: % % Fortran code WIGNER6J.F based on original by Schulten and Gordon % g77 -o $PFILES/wigner6j $FFILES/wigner6j.f $FFILES/drc6j.f ; wigner6j % sprintf('%23.16e\n',wigner6j(0,8,7,6.5,7.5,7.5)) % % Last modified by fjsimons-at-alum.mit.edu, 1/11/2007 if ~isstr(l2) % Overflow parameters %huge=sqrt(1.79D+308/20); huge=sqrt(realmax/20); sqhuge=sqrt(huge); tiny=1/huge; srtiny=1/sqhuge; % Limits for L1 l1min=max(abs(l2-l3),abs(l5-l6)); l1max=min(l2+l3,l5+l6); % Check error condition 4. if mod(l1max-l1min,1) error('l1max-l1min not integer') end % disp(sprintf('Computation from %i to %i',l1min,l1max)) % Check error conditions 1, 2, and 3. if mod(l2+l3+l5+l6,1) || mod(l4+l2+l6,1) % warning('l2+l3+l5+l6 or l4+l2+l6 not integer') w6j=repmat(0,l1max+1,1)'; L=0:l1max; return elseif l4+l2-l6<0 || l4-l2+l6<0 || -l4+l2+l6<0 % warning('l2, l4, l6 triangular condition not satisfied') w6j=repmat(0,l1max+1,1)'; L=0:l1max; return elseif l4-l5+l3<0 || l4+l5-l3<0 || -l4+l5+l3<0 % warning('l3, l4, l5 triangular condition not satisfied') w6j=repmat(0,l1max+1,1)'; L=0:l1max; return end % Compute single coefficient directly by analytic formula if l1min1 dv=2*(l2*(l2+1)*l5*(l5+1)+l3*(l3+1)*l6*(l6+1)-l1*(l1-1)*l4*(l4+1))... -(l2*(l2+1)+l3*(l3+1)-l1*(l1-1))*(l5*(l5+1)+l6*(l6+1)-l1*(l1-1)); denom=(l1-1)*newfac; if ~(lstep-2<=0) c1old=abs(c1); end c1=-(2*l1-1)*dv/denom; else % If L1=1, (L1-1) has to be factored out of DV, hence c1=-2*(l2*(l2+1)+l5*(l5+1)-l4*(l4+1))/newfac; end if ~(lstep>2) % If L1=L1MIN+1, the third term in recursion equation vanishes x=srtiny*c1; w6j(2)=x; sum1=sum1+tiny*(2*l1+1)*c1^2; if lstep==nfin sumuni=sum1; % Normalize 6j coefficients cnorm=1/sqrt((2*l4+1)*sumuni); % Sign convention for last 6j coefficient determines overall phase sign1=sign(w6j(nfin)); sign2=(-1)^floor(l2+l3+l5+l6); if sign1*sign2<=0 cnorm=-cnorm; end if abs(cnorm)<1 thresh=tiny/abs(cnorm); for n=1:nfin if abs(w6j(n))2) y=srtiny*c1; w6j(nfin-1)=y; if lstep==nstep2 break end sumbac=sum2; sum2=sum2+(2*l1-3)*c1^2*tiny; else c2=-(l1-1)*oldfac/denom; y=c1*w6j(nfinp2-lstep)+c2*w6j(nfinp3-lstep); if lstep==nstep2 break else w6j(nfinp1-lstep)=y; sumbac=sum2; sum2=sum2+(2*l1-3)*y*y; if ~(abs(y)