Skip to content

Rotation vector

beignet.apply_rotation_vector

apply_rotation_vector(input, rotation, degrees=False, inverse=False)

Rotates vectors in three-dimensional space using rotation vectors.

Note

This function interprets the rotation of the original frame to the final frame as either a projection, where it maps the components of vectors from the final frame to the original frame, or as a physical rotation, integrating the vectors into the original frame during the rotation process. Consequently, the vector components are maintained in the original frame’s perspective both before and after the rotation.

Parameters:

Name Type Description Default
input (Tensor, shape(..., 3))

Each vector represents a vector in three-dimensional space. The number of rotation vectors and number of vectors must follow standard broadcasting rules: either one of them equals unity or they both equal each other.

required
rotation (Tensor, shape(..., 4))

Rotation vectors.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False
inverse bool

If True the inverse of the rotation vectors are applied to the input vectors. Default, False.

False

Returns:

Name Type Description
output Tensor, shape=(..., 3)

Rotated vectors.

Source code in src/beignet/_apply_rotation_vector.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def apply_rotation_vector(
    input: Tensor,
    rotation: Tensor,
    degrees: bool | None = False,
    inverse: bool | None = False,
) -> Tensor:
    r"""
    Rotates vectors in three-dimensional space using rotation vectors.

    Note
    ----
    This function interprets the rotation of the original frame to the final
    frame as either a projection, where it maps the components of vectors from
    the final frame to the original frame, or as a physical rotation,
    integrating the vectors into the original frame during the rotation
    process. Consequently, the vector components are maintained in the original
    frame’s perspective both before and after the rotation.

    Parameters
    ----------
    input : Tensor, shape (..., 3)
        Each vector represents a vector in three-dimensional space. The number
        of rotation vectors and number of vectors must follow standard
        broadcasting rules: either one of them equals unity or they both equal
        each other.

    rotation : Tensor, shape (..., 4)
        Rotation vectors.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    inverse : bool, optional
        If `True` the inverse of the rotation vectors are applied to the input
        vectors. Default, `False`.

    Returns
    -------
    output : Tensor, shape=(..., 3)
        Rotated vectors.
    """
    return apply_rotation_matrix(
        input,
        quaternion_to_rotation_matrix(
            rotation_vector_to_quaternion(
                rotation,
                degrees,
            ),
        ),
        inverse,
    )

beignet.compose_rotation_vector

compose_rotation_vector(input, other, degrees=False)

Compose rotation vectors.

Parameters:

Name Type Description Default
input Tensor, shape=(..., 4)

Rotation vectors.

required
other Tensor, shape=(..., 4)

Rotation vectors.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False

Returns:

Name Type Description
output Tensor, shape=(..., 4)

Composed rotation vectors.

Source code in src/beignet/_compose_rotation_vector.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def compose_rotation_vector(
    input: Tensor,
    other: Tensor,
    degrees: bool | None = False,
) -> Tensor:
    r"""
    Compose rotation vectors.

    Parameters
    ----------
    input : Tensor, shape=(..., 4)
        Rotation vectors.

    other : Tensor, shape=(..., 4)
        Rotation vectors.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    Returns
    -------
    output : Tensor, shape=(..., 4)
        Composed rotation vectors.
    """
    return quaternion_to_rotation_vector(
        compose_quaternion(
            rotation_vector_to_quaternion(
                input,
                degrees,
            ),
            rotation_vector_to_quaternion(
                other,
                degrees,
            ),
        ),
        degrees,
    )

beignet.invert_rotation_vector

invert_rotation_vector(input)

Invert rotation vectors.

Parameters:

Name Type Description Default
input (Tensor, shape(..., 3))

Rotation vectors.

required

Returns:

Name Type Description
inverted_rotation_vectors (Tensor, shape(..., 3))

Inverted rotation vectors.

Source code in src/beignet/_invert_rotation_vector.py
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
def invert_rotation_vector(
    input: Tensor,
) -> Tensor:
    r"""
    Invert rotation vectors.

    Parameters
    ----------
    input : Tensor, shape (..., 3)
        Rotation vectors.

    Returns
    -------
    inverted_rotation_vectors : Tensor, shape (..., 3)
        Inverted rotation vectors.
    """
    return -input

beignet.random_rotation_vector

random_rotation_vector(size, degrees=False, *, generator=None, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False, pin_memory=False)

Generate random rotation vectors.

Parameters:

Name Type Description Default
size int

Output size.

required
degrees bool
False
generator Generator

Psuedo-random number generator. Default, None.

None
out Tensor

Output tensor. Default, None.

None
dtype dtype

Type of the returned tensor. Default, global default.

None
layout layout

Layout of the returned tensor. Default, torch.strided.

strided
device device

Device of the returned tensor. Default, current device for the default tensor type.

None
requires_grad bool

Whether autograd records operations on the returned tensor. Default, False.

False
pin_memory bool

If True, returned tensor is allocated in pinned memory. Default, False.

False

Returns:

Name Type Description
random_rotation_vectors (Tensor, shape(..., 3))

Random rotation vectors.

Source code in src/beignet/_random_rotation_vector.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def random_rotation_vector(
    size: int,
    degrees: bool = False,
    *,
    generator: Generator | None = None,
    out: Tensor | None = None,
    dtype: torch.dtype | None = None,
    layout: torch.layout | None = torch.strided,
    device: torch.device | None = None,
    requires_grad: bool | None = False,
    pin_memory: bool | None = False,
) -> Tensor:
    r"""
    Generate random rotation vectors.

    Parameters
    ----------
    size : int
        Output size.

    degrees

    generator : torch.Generator, optional
        Psuedo-random number generator. Default, `None`.

    out : Tensor, optional
        Output tensor. Default, `None`.

    dtype : torch.dtype, optional
        Type of the returned tensor. Default, global default.

    layout : torch.layout, optional
        Layout of the returned tensor. Default, `torch.strided`.

    device : torch.device, optional
        Device of the returned tensor. Default, current device for the default
        tensor type.

    requires_grad : bool, optional
        Whether autograd records operations on the returned tensor. Default,
        `False`.

    pin_memory : bool, optional
        If `True`, returned tensor is allocated in pinned memory. Default,
        `False`.

    Returns
    -------
    random_rotation_vectors : Tensor, shape (..., 3)
        Random rotation vectors.
    """
    return quaternion_to_rotation_vector(
        random_quaternion(
            size,
            generator=generator,
            out=out,
            dtype=dtype,
            layout=layout,
            device=device,
            requires_grad=requires_grad,
            pin_memory=pin_memory,
        ),
        degrees,
    )

beignet.rotation_vector_identity

rotation_vector_identity(size, degrees=False, *, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False)

Identity rotation vectors.

Parameters:

Name Type Description Default
size int

Output size.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False
out Tensor

Output tensor. Default, None.

None
dtype dtype

Type of the returned tensor. Default, global default.

None
layout layout

Layout of the returned tensor. Default, torch.strided.

strided
device device

Device of the returned tensor. Default, current device for the default tensor type.

None
requires_grad bool

Whether autograd records operations on the returned tensor. Default, False.

False

Returns:

Name Type Description
identity_rotation_vectors (Tensor, shape(size, 3))

Identity rotation vectors.

Source code in src/beignet/_rotation_vector_identity.py
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
def rotation_vector_identity(
    size: int,
    degrees: bool = False,
    *,
    out: Tensor | None = None,
    dtype: torch.dtype | None = None,
    layout: torch.layout | None = torch.strided,
    device: torch.device | None = None,
    requires_grad: bool | None = False,
) -> Tensor:
    r"""
    Identity rotation vectors.

    Parameters
    ----------
    size : int
        Output size.

    degrees : bool
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    out : Tensor, optional
        Output tensor. Default, `None`.

    dtype : torch.dtype, optional
        Type of the returned tensor. Default, global default.

    layout : torch.layout, optional
        Layout of the returned tensor. Default, `torch.strided`.

    device : torch.device, optional
        Device of the returned tensor. Default, current device for the default
        tensor type.

    requires_grad : bool, optional
        Whether autograd records operations on the returned tensor. Default,
        `False`.

    Returns
    -------
    identity_rotation_vectors : Tensor, shape (size, 3)
        Identity rotation vectors.
    """
    return quaternion_to_rotation_vector(
        quaternion_identity(
            size,
            out=out,
            dtype=dtype,
            layout=layout,
            device=device,
            requires_grad=requires_grad,
        ),
        degrees,
    )

beignet.rotation_vector_magnitude

rotation_vector_magnitude(input, degrees=False)

Rotation vector magnitudes.

Parameters:

Name Type Description Default
input (Tensor, shape(..., 3))

Rotation vectors.

required
degrees bool

If True, magnitudes are assumed to be in degrees. Default, False.

False

Returns:

Name Type Description
rotation_vector_magnitudes (Tensor, shape(...))

Angles in radians. Magnitudes will be in the range :math:[0, \pi].

Source code in src/beignet/_rotation_vector_magnitude.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def rotation_vector_magnitude(
    input: Tensor,
    degrees: bool | None = False,
) -> Tensor:
    r"""
    Rotation vector magnitudes.

    Parameters
    ----------
    input : Tensor, shape (..., 3)
        Rotation vectors.

    degrees : bool, optional
        If `True`, magnitudes are assumed to be in degrees. Default, `False`.

    Returns
    -------
    rotation_vector_magnitudes : Tensor, shape (...)
        Angles in radians. Magnitudes will be in the range :math:`[0, \pi]`.
    """
    return quaternion_magnitude(
        rotation_vector_to_quaternion(
            input,
            degrees,
        ),
    )

beignet.rotation_vector_mean

rotation_vector_mean(input, weight=None, degrees=False)

Compose rotation vectors.

Parameters:

Name Type Description Default
input Tensor, shape=(..., 4)

Rotation vectors.

required
weight Tensor, shape=(..., 4)

Relative importance of rotation matrices.

None
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False

Returns:

Name Type Description
output Tensor, shape=(..., 4)

Rotation vectors mean.

Source code in src/beignet/_rotation_vector_mean.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def rotation_vector_mean(
    input: Tensor,
    weight: Tensor | None = None,
    degrees: bool | None = False,
) -> Tensor:
    r"""
    Compose rotation vectors.

    Parameters
    ----------
    input : Tensor, shape=(..., 4)
        Rotation vectors.

    weight : Tensor, shape=(..., 4), optional
        Relative importance of rotation matrices.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    Returns
    -------
    output : Tensor, shape=(..., 4)
        Rotation vectors mean.
    """
    return quaternion_to_rotation_vector(
        quaternion_mean(
            rotation_vector_to_quaternion(
                input,
                degrees,
            ),
            weight,
        ),
        degrees,
    )

beignet.rotation_vector_to_euler_angle

rotation_vector_to_euler_angle(input, axes, degrees=False)

Convert rotation vectors to Euler angles.

Parameters:

Name Type Description Default
input Tensor, shape=(..., 3)

Rotation vectors.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False

Returns:

Name Type Description
output Tensor, shape=(..., 3)

Euler angles. The returned Euler angles are in the range:

* First angle: :math:`(-180, 180]` degrees (inclusive)
* Second angle:
    * :math:`[-90, 90]` degrees if all axes are different
      (e.g., :math:`xyz`)
    * :math:`[0, 180]` degrees if first and third axes are the same
      (e.g., :math:`zxz`)
* Third angle: :math:`[-180, 180]` degrees (inclusive)
Source code in src/beignet/_rotation_vector_to_euler_angle.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def rotation_vector_to_euler_angle(
    input: Tensor,
    axes: str,
    degrees: bool = False,
) -> Tensor:
    r"""
    Convert rotation vectors to Euler angles.

    Parameters
    ----------
    input : Tensor, shape=(..., 3)
        Rotation vectors.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    Returns
    -------
    output : Tensor, shape=(..., 3)
        Euler angles. The returned Euler angles are in the range:

            * First angle: :math:`(-180, 180]` degrees (inclusive)
            * Second angle:
                * :math:`[-90, 90]` degrees if all axes are different
                  (e.g., :math:`xyz`)
                * :math:`[0, 180]` degrees if first and third axes are the same
                  (e.g., :math:`zxz`)
            * Third angle: :math:`[-180, 180]` degrees (inclusive)
    """
    return quaternion_to_euler_angle(
        rotation_vector_to_quaternion(
            input,
            degrees,
        ),
        axes,
        degrees,
    )

beignet.rotation_vector_to_quaternion

rotation_vector_to_quaternion(input, degrees=False, canonical=False)

Convert rotation vector to rotation quaternion.

Parameters:

Name Type Description Default
input Tensor, shape=(..., 3)

Rotation vector.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False
canonical bool

Whether to map the redundant double cover of rotation space to a unique canonical single cover. If True, then the rotation quaternion is chosen from :math:{q, -q} such that the :math:w term is positive. If the :math:w term is :math:0, then the rotation quaternion is chosen such that the first non-zero term of the :math:x, :math:y, and :math:z terms is positive.

False

Returns:

Name Type Description
output Tensor, shape=(..., 4)

Rotation quaternion.

Source code in src/beignet/_rotation_vector_to_quaternion.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
def rotation_vector_to_quaternion(
    input: Tensor,
    degrees: bool | None = False,
    canonical: bool | None = False,
) -> Tensor:
    r"""
    Convert rotation vector to rotation quaternion.

    Parameters
    ----------
    input : Tensor, shape=(..., 3)
        Rotation vector.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    canonical : bool, optional
        Whether to map the redundant double cover of rotation space to a unique
        canonical single cover. If `True`, then the rotation quaternion is
        chosen from :math:`{q, -q}` such that the :math:`w` term is positive.
        If the :math:`w` term is :math:`0`, then the rotation quaternion is
        chosen such that the first non-zero term of the :math:`x`, :math:`y`,
        and :math:`z` terms is positive.

    Returns
    -------
    output : Tensor, shape=(..., 4)
        Rotation quaternion.
    """
    if degrees:
        input = torch.deg2rad(input)

    output = torch.empty(
        [input.shape[0], 4],
        dtype=input.dtype,
        layout=input.layout,
        device=input.device,
    )

    for j in range(input.shape[0]):
        t = input[j, 0] ** 2.0
        u = input[j, 1] ** 2.0
        v = input[j, 2] ** 2.0

        y = torch.sqrt(t + u + v)

        if y < 0.001:
            scale = 0.5 - y**2.0 / 48.0 + y**2.0 * y**2.0 / 3840.0
        else:
            scale = torch.sin(y / 2) / y

        output[j, :-1] = input[j] * scale

        output[j, 3] = torch.cos(y / 2)

    if canonical:
        for j in range(output.shape[0]):
            a = output[j, 0]
            b = output[j, 1]
            c = output[j, 2]
            d = output[j, 3]

            if d == 0 and (a == 0 & (b == 0 & c < 0 | b < 0) | a < 0) | d < 0:
                output[j] = -output[j]

    return output

beignet.rotation_vector_to_rotation_matrix

rotation_vector_to_rotation_matrix(input, degrees=False)

Convert rotation vectors to rotation matrices.

Parameters:

Name Type Description Default
input Tensor, shape=(..., 3)

Rotation vectors.

required
degrees bool

If True, rotation vector magnitudes are assumed to be in degrees. Default, False.

False

Returns:

Name Type Description
output Tensor, shape=(..., 3, 3)

Rotation matrices.

Source code in src/beignet/_rotation_vector_to_rotation_matrix.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
def rotation_vector_to_rotation_matrix(
    input: Tensor,
    degrees: bool | None = False,
) -> Tensor:
    r"""
    Convert rotation vectors to rotation matrices.

    Parameters
    ----------
    input : Tensor, shape=(..., 3)
        Rotation vectors.

    degrees : bool, optional
        If `True`, rotation vector magnitudes are assumed to be in degrees.
        Default, `False`.

    Returns
    -------
    output : Tensor, shape=(..., 3, 3)
        Rotation matrices.
    """
    return quaternion_to_rotation_matrix(
        rotation_vector_to_quaternion(
            input,
            degrees,
        ),
    )