(q, v)
return (v + 2 * (q[:, :1] * uv + uuv)).view(original_shape)
Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
Rotate vector ( s ) v about the rotation described by quaternion ( s ) q . Expects a tensor of shape ( * 4 ) for q and a tensor of shape ( * 3 ) for v where * denotes any number of dimensions . Returns a tensor of shape ( * 3 ) .
def qrot(q, v):
    """
    Rotate vector(s) v about the rotation described by quaternion(s) q.
    Expects a tensor of shape (*, 4) for q and a tensor of shape (*, 3) for v,
    where * denotes any number of dimensions.
    Returns a tensor of shape (*, 3).
    """
    assert q.shape[-1] == 4
    assert v.shape[-1] == 3
    assert q.shape[:-1] == v.shape[:-1]

    original_shape = list(v.shape)
    q = q.view(-1, 4)
    v = v.view(-1, 3)

    qvec = q[:, 1:]
    uv = torch.cross(qvec, v, dim=1)
    uuv = torch.cross(qvec, uv, dim=1)
    return (v + 2 * (q[:, :1] * uv + uuv)).view(original_shape)
def qrot ( q , v ) : assert q . shape [ - 1 ] == 4 assert v . shape [ - 1 ] == 3 assert q . shape [ : - 1 ] == v . shape [ : - 1 ] original_shape = list ( v . shape ) q = q . view ( - 1 , 4 ) v = v . view ( - 1 , 3 ) qvec = q [ : , 1 : ] uv = torch . cross ( qvec , v , dim = 1 ) uuv = torch . cross ( qvec , uv , dim = 1 ) return ( v + 2 * ( q [ : , : 1 ] * uv + uuv ) ) . view ( original_shape )