Skip to content

Rotation matrix

beignet.apply_rotation_matrix

apply_rotation_matrix(input, rotation, inverse=False)

Rotates vectors in three-dimensional space using rotation matrices.

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 matrices 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(..., 3, 3))

Rotation matrices.

required
inverse bool

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

False

Returns:

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

Rotated vectors.

Source code in src/beignet/_apply_rotation_matrix.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
def apply_rotation_matrix(
    input: Tensor,
    rotation: Tensor,
    inverse: bool | None = False,
) -> Tensor:
    r"""
    Rotates vectors in three-dimensional space using rotation matrices.

    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 matrices and number of vectors must follow standard
        broadcasting rules: either one of them equals unity or they both equal
        each other.

    rotation : Tensor, shape (..., 3, 3)
        Rotation matrices.

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

    Returns
    -------
    rotated_vectors : Tensor, shape (..., 3)
        Rotated vectors.
    """
    if inverse:
        output = torch.einsum("ikj, ik -> ij", rotation, input)
    else:
        output = torch.einsum("ijk, ik -> ij", rotation, input)

    return output

beignet.compose_rotation_matrix

compose_rotation_matrix(input, other)

Compose rotation matrices.

Parameters:

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

Rotation matrices.

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

Rotation matrices.

required

Returns:

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

Composed rotation matrices.

Source code in src/beignet/_compose_rotation_matrix.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
def compose_rotation_matrix(
    input: Tensor,
    other: Tensor,
) -> Tensor:
    r"""
    Compose rotation matrices.

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

    other : Tensor, shape=(..., 3, 3)
        Rotation matrices.

    Returns
    -------
    output : Tensor, shape=(..., 3, 3)
        Composed rotation matrices.
    """
    return quaternion_to_rotation_matrix(
        compose_quaternion(
            rotation_matrix_to_quaternion(input),
            rotation_matrix_to_quaternion(other),
        ),
    )

beignet.invert_rotation_matrix

invert_rotation_matrix(input)

Invert rotation matrices.

Parameters:

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

Rotation matrices.

required

Returns:

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

Inverted rotation matrices.

Source code in src/beignet/_invert_rotation_matrix.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
def invert_rotation_matrix(input: Tensor) -> Tensor:
    r"""
    Invert rotation matrices.

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

    Returns
    -------
    inverted_rotation_matrices : Tensor, shape (..., 3, 3)
        Inverted rotation matrices.
    """
    return torch.transpose(input, -2, -1)

beignet.random_rotation_matrix

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

Generate random rotation matrices.

Parameters:

Name Type Description Default
size int

Output size.

required
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_matrices (Tensor, shape(..., 3, 3))

Random rotation matrices.

Source code in src/beignet/_random_rotation_matrix.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
def random_rotation_matrix(
    size: int,
    *,
    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 matrices.

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

    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_matrices : Tensor, shape (..., 3, 3)
        Random rotation matrices.
    """
    return quaternion_to_rotation_matrix(
        random_quaternion(
            size,
            generator=generator,
            out=out,
            dtype=dtype,
            layout=layout,
            device=device,
            requires_grad=requires_grad,
            pin_memory=pin_memory,
        ),
    )

beignet.rotation_matrix_identity

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

Identity rotation matrices.

Parameters:

Name Type Description Default
size int

Output size.

required
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_matrices (Tensor, shape(size, 3, 3))

Identity rotation matrices.

Source code in src/beignet/_rotation_matrix_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
def rotation_matrix_identity(
    size: int,
    *,
    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 matrices.

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

    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_matrices : Tensor, shape (size, 3, 3)
        Identity rotation matrices.
    """
    return quaternion_to_rotation_matrix(
        quaternion_identity(
            size,
            out=out,
            dtype=dtype,
            layout=layout,
            device=device,
            requires_grad=requires_grad,
        ),
    )

beignet.rotation_matrix_magnitude

rotation_matrix_magnitude(input)

Rotation matrix magnitudes.

Parameters:

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

Rotation matrices.

required

Returns:

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

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

Source code in src/beignet/_rotation_matrix_magnitude.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def rotation_matrix_magnitude(input: Tensor) -> Tensor:
    r"""
    Rotation matrix magnitudes.

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

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

beignet.rotation_matrix_mean

rotation_matrix_mean(input, weight=None)

Parameters:

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

Rotation matrices.

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

Relative importance of rotation matrices.

None

Returns:

Name Type Description
output Tensor, shape=(..., 3, 3)
Source code in src/beignet/_rotation_matrix_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
def rotation_matrix_mean(
    input: Tensor,
    weight: Tensor | None = None,
) -> Tensor:
    r"""
    Parameters
    ----------
    input : Tensor, shape=(..., 3, 3)
        Rotation matrices.

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

    Returns
    -------
    output : Tensor, shape=(..., 3, 3)
    """
    return quaternion_to_rotation_matrix(
        quaternion_mean(
            rotation_matrix_to_quaternion(
                input,
            ),
            weight,
        ),
    )

beignet.rotation_matrix_to_euler_angle

rotation_matrix_to_euler_angle(input, axes, degrees=False)

Convert rotation matrices to Euler angles.

Parameters:

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

Rotation matrices.

required
axes str

Axes. 1-3 characters belonging to the set {‘X’, ‘Y’, ‘Z’} for intrinsic rotations, or {‘x’, ‘y’, ‘z’} for extrinsic rotations. Extrinsic and intrinsic rotations cannot be mixed.

required
degrees bool

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

False

Returns:

Name Type Description
euler_angles (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_matrix_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
49
50
51
def rotation_matrix_to_euler_angle(
    input: Tensor,
    axes: str,
    degrees: bool = False,
) -> Tensor:
    r"""
    Convert rotation matrices to Euler angles.

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

    axes : str
        Axes. 1-3 characters belonging to the set {‘X’, ‘Y’, ‘Z’} for intrinsic
        rotations, or {‘x’, ‘y’, ‘z’} for extrinsic rotations. Extrinsic and
        intrinsic rotations cannot be mixed.

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

    Returns
    -------
    euler_angles : 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_matrix_to_quaternion(
            input,
        ),
        axes,
        degrees,
    )

beignet.rotation_matrix_to_quaternion

rotation_matrix_to_quaternion(input, canonical=False)

Convert rotation matrices to rotation quaternions.

Parameters:

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

Rotation matrices.

required
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_matrix_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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
def rotation_matrix_to_quaternion(
    input: Tensor,
    canonical: bool | None = False,
) -> Tensor:
    r"""
    Convert rotation matrices to rotation quaternions.

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

    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.
    """
    indexes = torch.empty(
        [4],
        dtype=input.dtype,
        layout=input.layout,
        device=input.device,
    )

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

    for j in range(input.shape[0]):
        indexes[0] = input[j, 0, 0]
        indexes[1] = input[j, 1, 1]
        indexes[2] = input[j, 2, 2]
        indexes[3] = input[j, 0, 0] + input[j, 1, 1] + input[j, 2, 2]

        index, maximum = 0, indexes[0]

        for k in range(1, 4):
            if indexes[k] > maximum:
                index, maximum = k, indexes[k]

        if index == 3:
            output[j, 0] = input[j, 2, 1] - input[j, 1, 2]
            output[j, 1] = input[j, 0, 2] - input[j, 2, 0]
            output[j, 2] = input[j, 1, 0] - input[j, 0, 1]
            output[j, 3] = 1.0 + indexes[3]
        else:
            t = index
            u = (t + 1) % 3
            v = (u + 1) % 3

            output[j, t] = 1.0 - indexes[3] + 2.0 * input[j, t, t]
            output[j, u] = input[j, u, t] + input[j, t, u]
            output[j, v] = input[j, v, t] + input[j, t, v]
            output[j, 3] = input[j, v, u] - input[j, u, v]

        a = output[j, 0] ** 2.0
        b = output[j, 1] ** 2.0
        c = output[j, 2] ** 2.0
        d = output[j, 3] ** 2.0

        output[j] = output[j] / torch.sqrt(a + b + c + d)

    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_matrix_to_rotation_vector

rotation_matrix_to_rotation_vector(input, degrees=False)

Convert rotation matrices to rotation vectors.

Parameters:

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

Rotation matrices.

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)

Rotation vectors.

Source code in src/beignet/_rotation_matrix_to_rotation_vector.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_matrix_to_rotation_vector(
    input: Tensor,
    degrees: bool = False,
) -> Tensor:
    r"""
    Convert rotation matrices to rotation vectors.

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

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

    Returns
    -------
    output : Tensor, shape=(..., 3)
        Rotation vectors.
    """
    return quaternion_to_rotation_vector(
        rotation_matrix_to_quaternion(
            input,
        ),
        degrees,
    )