| import os
|
| import torch
|
|
|
|
|
|
|
|
|
|
|
| _Jd = torch.load(os.path.join(os.path.dirname(__file__), "Jd.pt"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| def wigner_D(l, alpha, beta, gamma):
|
| if not l < len(_Jd):
|
| raise NotImplementedError(
|
| f"wigner D maximum l implemented is {len(_Jd) - 1}, send us an email to ask for more"
|
| )
|
|
|
| alpha, beta, gamma = torch.broadcast_tensors(alpha, beta, gamma)
|
| J = _Jd[l].to(dtype=alpha.dtype, device=alpha.device)
|
| Xa = _z_rot_mat(alpha, l)
|
| Xb = _z_rot_mat(beta, l)
|
| Xc = _z_rot_mat(gamma, l)
|
| return Xa @ J @ Xb @ J @ Xc
|
|
|
|
|
| def _z_rot_mat(angle, l):
|
| shape, device, dtype = angle.shape, angle.device, angle.dtype
|
| M = angle.new_zeros((*shape, 2 * l + 1, 2 * l + 1))
|
| inds = torch.arange(0, 2 * l + 1, 1, device=device)
|
| reversed_inds = torch.arange(2 * l, -1, -1, device=device)
|
| frequencies = torch.arange(l, -l - 1, -1, dtype=dtype, device=device)
|
| M[..., inds, reversed_inds] = torch.sin(frequencies * angle[..., None])
|
| M[..., inds, inds] = torch.cos(frequencies * angle[..., None])
|
| return M |