def test_irr_repr(): """ This test tests that - irr_repr - compose - spherical_harmonics are compatible Y(Z(alpha) Y(beta) Z(gamma) x) = D(alpha, beta, gamma) Y(x) with x = Z(a) Y(b) eta """ for order in range(7): a, b = torch.rand(2) alpha, beta, gamma = torch.rand(3) ra, rb, _ = compose(alpha, beta, gamma, a, b, 0) Yrx = spherical_harmonics(order, ra, rb) clear_spherical_harmonics_cache() Y = spherical_harmonics(order, a, b) clear_spherical_harmonics_cache() DrY = irr_repr(order, alpha, beta, gamma) @ Y d, r = (Yrx - DrY).abs().max(), Y.abs().max() print(d.item(), r.item()) assert d < 1e-10 * r, d / r
def test_basis_transformation_Q_J(): rand_angles = torch.rand(4, 3) J, order_out, order_in = 1, 1, 1 Q_J = basis_transformation_Q_J(J, order_in, order_out).float() assert all( torch.allclose( get_R_tensor(order_out, order_in, a, b, c) @ Q_J, Q_J @ irr_repr(J, a, b, c)) for a, b, c in rand_angles)
def sylvester_submatrix(order_out, order_in, J, a, b, c): ''' generate Kronecker product matrix for solving the Sylvester equation in subspace J ''' R_tensor = get_R_tensor(order_out, order_in, a, b, c) # [m_out * m_in, m_out * m_in] R_irrep_J = irr_repr(J, a, b, c) # [m, m] R_tensor_identity = torch.eye(R_tensor.shape[0]) R_irrep_J_identity = torch.eye(R_irrep_J.shape[0]) return kron(R_tensor, R_irrep_J_identity) - kron( R_tensor_identity, R_irrep_J.t()) # [(m_out * m_in) * m, (m_out * m_in) * m]
def get_R_tensor(order_out, order_in, a, b, c): return kron(irr_repr(order_out, a, b, c), irr_repr(order_in, a, b, c))