import torch


def rodrigues(theta, eps=1e-8):
    """Rodrigues, Axis Angle to Quaternion.
    Args:
        theta: tensor of shape `[..., 3]`.
    Returns:
        quaternion: of shape `[...,4]` 
    """
    angle = torch.norm(theta + eps, p=2, dim=-1, keepdim=True)
    normalized = torch.div(theta, angle)
    angle = angle * 0.5
    v_cos = torch.cos(angle)
    v_sin = torch.sin(angle)
    quat = torch.cat([v_cos, v_sin * normalized], dim=-1)
    return quat