-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add accurate computations for ell>29 #12
Comments
Hi, Could you please explain how I can use the Wigner_D_element function for large ell?
|
I really don't have time to work on the method I suggested above, but there is another way you could try, which I've already coded but haven't really brought into the code. I made a pull request #15 some time ago, but abandoned it because I didn't actually need the large
import numpy as np
from sympy import pi
from sympy.physics.quantum.spin import Rotation
import mpmath
mpmath.mp.dps=128
ell_max=32
_binomial_coefficients = np.empty((((2*ell_max+1)*(2*ell_max+2))//2,), dtype=float)
_ladder_operator_coefficients = np.empty((((ell_max+2)*ell_max+1),), dtype=float)
_Delta = np.empty(((4*ell_max**3 + 12*ell_max**2 + 11*ell_max + 3)//3,), dtype=float)
i=0
for n in range(2*ell_max+1):
for k in range(n+1):
_binomial_coefficients[i]=float(mpmath.binomial(n,k))
i+=1
print(i, _binomial_coefficients.shape)
np.save('binomial_coefficients',_binomial_coefficients)
i=0
for ell in range(ell_max+1):
for m in range(-ell,ell+1):
_ladder_operator_coefficients[i]=mpmath.sqrt(ell*(ell+1)-m*(m+1))
i+=1
print(i, _ladder_operator_coefficients.shape)
np.save('ladder_operator_coefficients',_ladder_operator_coefficients)
def real(x):
try:
return x.real
except AttributeError:
return x
i=0
for ell in range(ell_max+1):
for mp in range(-ell,ell+1):
for m in range(-ell,ell+1):
_Delta[i] = real(complex(Rotation.D(ell, mp, m, 0,pi/2,0).doit().evalf(n=32)))
i += 1
print(i, _Delta.shape)
np.save('Delta',_Delta)
Also note that if you want high performance with really large |
Thanks a lot for your quick reply. Calculation of the Wigner-D elements with your package is incredibly faster than sympy, which is why I was hoping to be able to use it for very large ell (up to around 1000). I will definitely look into instructions above and spinsfast to see if I can figure it out. |
It's faster than So, I recommend using something like |
Hi @moble, I'm also looking to get reduced Wigner-D elements for |m|,|m_p|<=2, up to ell~10^4. Would it be possible to get some pointers on how to do this with spinsfast? I took a look at the repo, but my untrained eye could not see which functions to use. Thanks! |
@NiallMac Sorry, I never saw your question, and just happen to be looking at this issue now, years later, when it's probably too late anyway. For the record: I should clarify that spinsfast specializes in converting functions to and from a mode representation, and it does this on a grid. So basically, if you're looking for a 𝔇 element for an arbitrary rotation, it's not going to help at all. Plus, for the case |m|,|m_p|<=2, there's going to be a lot of wasted cycles and memory. If you actually still care about this, I've started the successor of this package, the |
I won't be updating this package to compute ell>29 because, as mentioned above, this new package has been designed for that purpose. |
As explained in issue #7, the alternating sign in the sum for Wigner D elements causes huge numerical problems. It would be easy enough (now that I've changed how that sum is evaluated) to break this out into a separate C function that uses gmp to evaluate the sum. Hopefully, it would also be easy to link against gmp if gmpy2 is installed.
The text was updated successfully, but these errors were encountered: