kornia.geometry.liegroup#

A Lie group combines the concepts of a group and a smooth manifold in a single object.

A group is a non-empty set with an operation that satisfies the following constraints: the operation is associative, has an identity element, and every element of the set has an inverse element.

See more: Group

A Lie group \(G\) is a smooth manifold whose elements satisfy the group axioms. You can visualize a manifold as a curved, smooth (hyper-)surface, with no edges or spikes, embedded in a space of higher dimension.

See more: Manifold

In robotics, we say that our state vector evolves on this surface; that is, the manifold describes, or is defined by, the constraints imposed on the state.

Lie algebra#

A manifold and its tangent space at the identity

If \(M\) is the manifold that represents a Lie group, the tangent space at the identity is called the Lie algebra of \(M\). The Lie algebra \(m\) is a vector space. As such, its elements can be identified with vectors in \(R^d\), whose dimension \(d\) is the number of degrees of freedom of \(M\). For example, \(d = 3\) for the Lie group \(SO(3)\).

Lie group and Lie algebra#

Every Lie group has an associated Lie algebra. We relate the Lie group to its Lie algebra through the following facts:

  1. The Lie algebra \(m\) is a vector space. As such, its elements can be identified with vectors in \(R^d\), whose dimension \(d\) is the number of degrees of freedom of \(M\).

  2. The exponential map, \(\exp : m \rightarrow M\), exactly converts elements of the Lie algebra into elements of the group. The \(\log\) map is the inverse operation.

The exponential and logarithmic maps between a Lie group and its Lie algebra

Reference: A micro Lie theory for state estimation in robotics

Classes#

class kornia.geometry.liegroup.So3(q)[source]#

Base class to represent the So3 group.

The SO(3) is the group of all rotations about the origin of three-dimensional Euclidean space \(R^3\) under the operation of composition. See more: https://en.wikipedia.org/wiki/3D_rotation_group

We internally represent the rotation by a Quaternion.

Convention:
  • The tangent vector is the rotation vector, the axis times the angle in radians, and hat(v) is its cross-product matrix: hat(v) @ p equals torch.linalg.cross(v, p). log() is q.to_axis_angle(): it reads only the direction of q, within the range limits stated on Quaternion, and returns the principal vector, of norm at most \(\pi\), the same for q and -q below a half turn.

  • a * b composes like a.matrix() @ b.matrix(), so b acts first; s * p rotates points p of shape \((B, 3)\), a tensor or a Vector3, as \(R p\); and adjoint() is \(R\) itself. Rotations and rigid motions compares these with scipy, Sophus and Eigen.

  • A non-unit quaternion stands for the rotation of its direction \(q / |q|\), as for matrix(): matrix() and s * p normalise it where they use it, so matrix() is always a rotation and s * p keeps the norm of p. q returns the quaternion as stored, which keeps an nn.Parameter registered and following optimiser steps.

  • For a small \(\delta\), \(\exp(\omega + \delta) \approx \exp(\omega) \exp(J_r \delta) = \exp(J_l \delta) \exp(\omega)\), with \(J_r\) = right_jacobian(omega) and \(J_l\) = left_jacobian(omega) = right_jacobian(-omega).

  • from_matrix does not check its input by default: a reflection (det \(-1\)) is accepted without error and returns an So3 whose matrix() is not the input. check_rotation=True raises ValueError instead.

  • The quaternion is registered as module state following Quaternion’s buffer/parameter convention, including rotations produced by exp, identity, random, from_matrix and group operations.

  • matrix(), adjoint(), a * b and s * p compute in float32 for float16/bfloat16 inputs and return the input dtype, rounding once; float32 and float64 are evaluated in their own dtype.

Example

>>> q = Quaternion.identity()
>>> s = So3(q)
>>> s.q
tensor([1., 0., 0., 0.])
static Jl(vec)[source]#

Alias for left jacobian.

Parameters:

vec (Tensor) – the tangent vector of shape \((B, 3)\).

Return type:

Tensor

static Jr(vec)[source]#

Alias for right jacobian.

Parameters:

vec (Tensor) – the tangent vector of shape \((B, 3)\).

Return type:

Tensor

__init__(q)[source]#

Construct the base class.

Parameters:

q (Quaternion) – Quaternion with the shape of \((B, 4)\).

Example

>>> data = torch.tensor([[1., 0., 0., 0.], [0., 1., 0., 0.]])
>>> q = Quaternion(data)
>>> So3(q)
tensor([[1., 0., 0., 0.],
        [0., 1., 0., 0.]])
__mul__(right)[source]#

Compose two So3 transformations, or rotate points.

Both compute in float32 for float16/bfloat16 inputs and return the input dtype.

Parameters:

right (So3 | Vector3 | Tensor) – the other So3 transformation, or points of shape \((B, 3)\) as a tensor or a Vector3.

Return type:

So3 | Vector3 | Tensor

Returns:

The resulting So3 transformation, or the rotated points of the type of right.

__repr__()[source]#

Return repr(self).

Return type:

str

adjoint()[source]#

Return the adjoint matrix of shape \((B, 3, 3)\).

Return type:

Tensor

Example

>>> s = So3.identity()
>>> s.adjoint()
tensor([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.]])
static exp(v)[source]#

Convert elements of lie algebra to elements of lie group.

See more: https://vision.in.tum.de/_media/members/demmeln/nurlanov2021so3log.pdf

Parameters:

v (Tensor) – vector of shape \((B,3)\).

Return type:

So3

Example

>>> v = torch.zeros((2, 3))
>>> s = So3.exp(v)
>>> s
tensor([[1., 0., 0., 0.],
        [1., 0., 0., 0.]])
classmethod from_matrix(matrix, check_rotation=False)[source]#

Create So3 from a rotation matrix.

Parameters:
  • matrix (Tensor) – the rotation matrix to convert of shape \((B,3,3)\).

  • check_rotation (bool, optional) – if True, raise ValueError unless every input is a rotation matrix. The default False keeps the unchecked behaviour, under which a reflection such as diag(-1, 1, 1) is silently turned into the identity. Note that So2.from_matrix rejects the 2D reflection diag(1, -1) regardless. Default: False

Return type:

So3

Example

>>> m = torch.eye(3)
>>> s = So3.from_matrix(m)
>>> s
tensor([1., 0., 0., 0.])
classmethod from_wxyz(wxyz)[source]#

Create So3 from a torch.Tensor representing a quaternion.

Parameters:

wxyz (Tensor) – the quaternion to convert of shape \((B,4)\).

Return type:

So3

Example

>>> q = torch.tensor([1., 0., 0., 0.])
>>> s = So3.from_wxyz(q)
>>> s
tensor([1., 0., 0., 0.])
static hat(v)[source]#

Convert elements from vector space to lie algebra. Returns matrix of shape \((B,3,3)\).

Parameters:

v (Vector3 | Tensor) – Vector3 or torch.Tensor of shape \((B,3)\).

Return type:

Tensor

Example

>>> v = torch.ones((1,3))
>>> m = So3.hat(v)
>>> m
tensor([[[ 0., -1.,  1.],
         [ 1.,  0., -1.],
         [-1.,  1.,  0.]]])
classmethod identity(batch_size=None, device=None, dtype=None)[source]#

Create a So3 group representing an identity rotation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

So3

Example

>>> s = So3.identity()
>>> s
tensor([1., 0., 0., 0.])
>>> s = So3.identity(batch_size=2)
>>> s
tensor([[1., 0., 0., 0.],
        [1., 0., 0., 0.]])
inverse()[source]#

Return the inverse transformation.

Return type:

So3

Example

>>> s = So3.identity()
>>> s.inverse()
tensor([1., -0., -0., -0.])
static left_jacobian(vec)[source]#

Compute the left Jacobian of So3.

Parameters:

vec (Tensor) – the tangent vector of shape \((B, 3)\).

Return type:

Tensor

Example

>>> vec = torch.tensor([1., 2., 3.])
>>> So3.left_jacobian(vec)
tensor([[-0.0687, -0.2267,  0.5074],
        [ 0.5556,  0.1779,  0.3629],
        [-0.0141,  0.6236,  0.5890]])
log()[source]#

Convert elements of lie group to elements of lie algebra.

Return type:

Tensor

Example

>>> So3.identity(batch_size=2).log()
tensor([[0., 0., 0.],
        [0., 0., 0.]])
matrix()[source]#

Convert the quaternion to a rotation matrix of shape \((B,3,3)\).

The matrix is of the form:

\[\begin{split}\begin{bmatrix} 1-2y^2-2z^2 & 2xy-2zw & 2xz+2yw \\ 2xy+2zw & 1-2x^2-2z^2 & 2yz-2xw \\ 2xz-2yw & 2yz+2xw & 1-2x^2-2y^2\end{bmatrix}\end{split}\]

It computes in float32 for float16/bfloat16 inputs and returns the input dtype.

Example

>>> s = So3.identity()
>>> m = s.matrix()
>>> m
tensor([[1., 0., 0.],
        [0., 1., 0.],
        [0., 0., 1.]])
Return type:

Tensor

property q: Quaternion#

Return the underlying data with shape \((B,4)\).

classmethod random(batch_size=None, device=None, dtype=None)[source]#

Create a So3 group representing a random rotation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

So3

Example

>>> s = So3.random()
>>> s = So3.random(batch_size=3)
static right_jacobian(vec)[source]#

Compute the right Jacobian of So3.

Parameters:

vec (Tensor) – the tangent vector of shape \((B, 3)\).

Return type:

Tensor

Example

>>> vec = torch.tensor([1., 2., 3.])
>>> So3.right_jacobian(vec)
tensor([[-0.0687,  0.5556, -0.0141],
        [-0.2267,  0.1779,  0.6236],
        [ 0.5074,  0.3629,  0.5890]])
classmethod rot_x(x)[source]#

Construct a x-axis rotation.

Parameters:

x (Tensor) – the x-axis rotation angle.

Return type:

So3

classmethod rot_y(y)[source]#

Construct a y-axis rotation.

Parameters:

y (Tensor) – the y-axis rotation angle.

Return type:

So3

classmethod rot_z(z)[source]#

Construct a z-axis rotation.

Parameters:

z (Tensor) – the z-axis rotation angle.

Return type:

So3

static vee(omega)[source]#

Convert elements from lie algebra to vector space. Returns vector of shape \((B,3)\).

\[\begin{split}omega = \begin{bmatrix} 0 & -c & b \\ c & 0 & -a \\ -b & a & 0\end{bmatrix}\end{split}\]
Parameters:

omega (Tensor) – 3x3-matrix representing lie algebra.

Return type:

Tensor

Example

>>> v = torch.ones((1,3))
>>> omega = So3.hat(v)
>>> So3.vee(omega)
tensor([[1., 1., 1.]])
class kornia.geometry.liegroup.Se3(rotation, translation)[source]#

Base class to represent the Se3 group.

The SE(3) is the group of rigid body transformations about the origin of three-dimensional Euclidean space \(R^3\) under the operation of composition. See more: https://ingmec.ual.es/~jlblanco/papers/jlblanco2010geometry3D_techrep.pdf

Convention:
  • The tangent vector is \([\upsilon, \omega]\), translation first (Rotations and rigid motions maps it onto Sophus and GTSAM): exp rotates by So3.exp(omega) and translates by \(V(\omega) \upsilon\), hat is \([[\hat\omega, \upsilon], [0, 0]]\), and log is principal, with \(|\omega| \le \pi\).

  • matrix() is the 4x4 \([[R, t], [0, 1]]\). a * b is a.matrix() @ b.matrix(), so b acts first, and g * p is \(R p + t\). adjoint() is \([[R, \hat t R], [0, R]]\).

  • The rotation is an So3, whose storage and point-shape conventions apply: a non-unit quaternion stands for the rotation of its direction. from_matrix ignores the bottom row.

  • t is always a tensor registered as module state, whichever constructor built the pose; a Vector3 passed to the constructor is unwrapped. g * p returns a Vector3 only when p is one.

  • state_dict(), load_state_dict() and module device/dtype conversions include both the rotation and translation. Rotation state follows Quaternion’s buffer/parameter convention.

  • a * b and g * p compute in float32 for float16/bfloat16 inputs and return the input dtype, rounding \(R p + t\) once; matrix() and inverse() take the rotation from So3, which does the same.

Example

>>> q = Quaternion.identity()
>>> s = Se3(q, torch.ones(3))
>>> s.r
tensor([1., 0., 0., 0.])
>>> s.t
Parameter containing:
tensor([1., 1., 1.], requires_grad=True)
__init__(rotation, translation)[source]#

Construct the base class.

Internally represented by an So3 rotation and a translation 3-vector.

Parameters:
  • rotation (Quaternion | So3) – So3 group encompassing a rotation, or a Quaternion to wrap in one; it is stored as given, and a non-unit quaternion stands for the rotation of its direction.

  • translation (Vector3 | Tensor) – translation torch.Tensor with the shape of \((B, 3)\), or a Vector3 wrapping one; the tensor is what gets stored. It must have the rotation’s dtype and device.

Raises:
  • TypeCheckError – if the translation is an integer, bool or complex tensor (an nn.Parameter too), or its dtype differs from the rotation’s (inverse, adjoint and the other methods cannot combine them).

  • DeviceError – if the translation is on another device than the rotation.

Example

>>> from kornia.geometry.quaternion import Quaternion
>>> q = Quaternion.identity(batch_size=1)
>>> s = Se3(q, torch.ones((1, 3)))
>>> s.r
tensor([[1., 0., 0., 0.]])
>>> s.t
Parameter containing:
tensor([[1., 1., 1.]], requires_grad=True)
__mul__(right)[source]#

Compose two Se3 transformations, or transform points.

Both compute in float32 for float16/bfloat16 inputs and return the input dtype.

Parameters:

right (Se3 | Vector3 | Tensor) – the other Se3 transformation, or points as a tensor or Vector3 with the batch shape of the pose and a last dimension of 3.

Return type:

Se3 | Vector3 | Tensor

Returns:

The resulting Se3 transformation, or the transformed points.

__repr__()[source]#

Return repr(self).

Return type:

str

adjoint()[source]#

Return the adjoint matrix of shape \((B, 6, 6)\).

Return type:

Tensor

Example

>>> s = Se3.identity()
>>> s.adjoint()
tensor([[1., 0., 0., 0., 0., 0.],
        [0., 1., 0., 0., 0., 0.],
        [0., 0., 1., 0., 0., 0.],
        [0., 0., 0., 1., 0., 0.],
        [0., 0., 0., 0., 1., 0.],
        [0., 0., 0., 0., 0., 1.]], grad_fn=<CatBackward0>)
static exp(v)[source]#

Convert elements of lie algebra to elements of lie group.

Parameters:

v (Tensor) – vector of shape \((B, 6)\).

Return type:

Se3

Example

>>> v = torch.zeros((1, 6))
>>> s = Se3.exp(v)
>>> s.r
tensor([[1., 0., 0., 0.]])
>>> s.t
Parameter containing:
tensor([[0., 0., 0.]], requires_grad=True)
classmethod from_matrix(matrix, check_rotation=False)[source]#

Create a Se3 group from a matrix.

Parameters:
  • matrix (Tensor) – torch.Tensor of shape \((B, 4, 4)\).

  • check_rotation (bool, optional) – if True, raise ValueError unless the rotation block of every input is a rotation matrix. The default False keeps the unchecked behaviour, under which a reflection block such as diag(-1, 1, 1) yields a non-unit quaternion. Default: False

Return type:

Se3

Example

>>> s = Se3.from_matrix(torch.eye(4))
>>> s.r
tensor([1., 0., 0., 0.])
>>> s.t
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)
classmethod from_qxyz(qxyz)[source]#

Create a Se3 group from a quaternion and a translation vector.

Parameters:

qxyz (Tensor) – torch.Tensor of shape \((B, 7)\) laid out as [qw, qx, qy, qz, x, y, z], scalar first; the quaternion is stored as given, and a non-unit one stands for the rotation of its direction.

Return type:

Se3

Example

>>> qxyz = torch.tensor([0., 0., 0., 1., 0., 0., 1.])
>>> s = Se3.from_qxyz(qxyz)
>>> s.r
tensor([0., 0., 0., 1.])
>>> s.t
Parameter containing:
tensor([0., 0., 1.], requires_grad=True)
static hat(v)[source]#

Convert elements from vector space to lie algebra.

Parameters:

v (Tensor) – vector of shape \((B, 6)\).

Return type:

Tensor

Returns:

matrix of shape \((B, 4, 4)\).

Example

>>> v = torch.ones((1, 6))
>>> m = Se3.hat(v)
>>> m
tensor([[[ 0., -1.,  1.,  1.],
         [ 1.,  0., -1.,  1.],
         [-1.,  1.,  0.,  1.],
         [ 0.,  0.,  0.,  0.]]])
classmethod identity(batch_size=None, device=None, dtype=None)[source]#

Create a Se3 group representing an identity rotation and zero translation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

Se3

Example

>>> s = Se3.identity()
>>> s.r
tensor([1., 0., 0., 0.])
>>> s.t
Parameter containing:
tensor([0., 0., 0.], requires_grad=True)
inverse()[source]#

Return the inverse transformation.

Return type:

Se3

Example

>>> s = Se3(So3.identity(), torch.ones(3))
>>> s_inv = s.inverse()
>>> s_inv.r
tensor([1., -0., -0., -0.])
>>> s_inv.t
tensor([-1., -1., -1.], grad_fn=<SliceBackward0>)
log()[source]#

Convert elements of lie group to elements of lie algebra.

Return type:

Tensor

Example

>>> from kornia.geometry.quaternion import Quaternion
>>> q = Quaternion.identity()
>>> Se3(q, torch.zeros(3)).log()
tensor([0., 0., 0., 0., 0., 0.], grad_fn=<CatBackward0>)
matrix()[source]#

Return the matrix representation of shape \((B, 4, 4)\).

Return type:

Tensor

Example

>>> s = Se3(So3.identity(), torch.ones(3))
>>> s.matrix()
tensor([[1., 0., 0., 1.],
        [0., 1., 0., 1.],
        [0., 0., 1., 1.],
        [0., 0., 0., 1.]], grad_fn=<CopySlices>)
property quaternion: Quaternion#

Return the underlying rotation(Quaternion).

property r: So3#

Return the underlying rotation(So3).

classmethod random(batch_size=None, device=None, dtype=None)[source]#

Create a Se3 group representing a random transformation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

Se3

Example

>>> s = Se3.random()
>>> s = Se3.random(batch_size=3)
classmethod rot_x(x)[source]#

Construct a x-axis rotation.

Parameters:

x (Tensor) – the x-axis rotation angle.

Return type:

Se3

classmethod rot_y(y)[source]#

Construct a y-axis rotation.

Parameters:

y (Tensor) – the y-axis rotation angle.

Return type:

Se3

classmethod rot_z(z)[source]#

Construct a z-axis rotation.

Parameters:

z (Tensor) – the z-axis rotation angle.

Return type:

Se3

property rotation: So3#

Return the underlying rotation(So3).

property so3: So3#

Return the underlying rotation(So3).

property t: Tensor#

Return the underlying translation vector of shape \((B,3)\).

classmethod trans(x, y, z)[source]#

Construct a translation only Se3 instance.

Parameters:
  • x (Tensor) – the x-axis translation.

  • y (Tensor) – the y-axis translation.

  • z (Tensor) – the z-axis translation.

Return type:

Se3

classmethod trans_x(x)[source]#

Construct a x-axis translation.

Parameters:

x (Tensor) – the x-axis translation.

Return type:

Se3

classmethod trans_y(y)[source]#

Construct a y-axis translation.

Parameters:

y (Tensor) – the y-axis translation.

Return type:

Se3

classmethod trans_z(z)[source]#

Construct a z-axis translation.

Parameters:

z (Tensor) – the z-axis translation.

Return type:

Se3

property translation: Tensor#

Return the underlying translation vector of shape \((B,3)\).

static vee(omega)[source]#

Convert elements from lie algebra to vector space.

Parameters:

omega (Tensor) – 4x4-matrix representing lie algebra of shape \((B,4,4)\).

Return type:

Tensor

Returns:

vector of shape \((B,6)\).

Example

>>> v = torch.ones((1, 6))
>>> omega_hat = Se3.hat(v)
>>> Se3.vee(omega_hat)
tensor([[1., 1., 1., 1., 1., 1.]])
class kornia.geometry.liegroup.So2(z)[source]#

Base class to represent the So2 group.

The SO(2) is the group of all rotations about the origin of two-dimensional Euclidean space \(R^2\) under the operation of composition. See more: https://en.wikipedia.org/wiki/Orthogonal_group#Special_orthogonal_group

Convention:
  • Represents the rotation as a complex number z of shape \(()\) or \((B,)\); a \((B, 1)\) z or angle is accepted and read as \((B,)\). For unit \(z = \cos\theta + i \sin\theta\), matrix() is \([[\cos\theta, -\sin\theta], [\sin\theta, \cos\theta]]\). Non-unit z = a + i b is accepted and produces \([[a, -b], [b, a]]\), which rotates and scales by \(|z|\). The complex storage has no bfloat16 counterpart in PyTorch, so exp, identity, random and from_matrix raise TypeCheckError for bfloat16 values.

  • A positive angle rotates the x axis toward the y axis: counter-clockwise in a y-up frame, clockwise as displayed on y-down image axes. For a unit rotation, matrix() is the transpose of angle_to_rotation_matrix(), which takes degrees. log returns the angle in \([-\pi, \pi]\), and adjoint() is the 2x2 identity.

  • hat returns the so(2) generator \([[0, -\theta], [\theta, 0]]\) and vee reads its [1, 0] entry, so matrix_exp(hat(theta)) equals exp(theta).matrix().

  • Module dtype conversions act on the real and imaginary components together: .float() and .to(torch.float32) use complex64 state, while .double() and .to(torch.float64) use complex128. Device-only conversions preserve the complex precision, and explicit complex dtypes are also accepted. The complex checkpoint key _z and its shape are unchanged. .half() uses PyTorch’s experimental complex32 dtype. Since PyTorch has no complex bfloat16 dtype, .bfloat16() and .to(torch.bfloat16) keep the rotation’s existing complex precision while following any requested device move.

Example

>>> real = torch.tensor([0.6])
>>> imag = torch.tensor([0.8])
>>> So2(torch.complex(real, imag))
Parameter containing:
tensor([0.6000+0.8000j], requires_grad=True)
__init__(z)[source]#

Construct the base class.

Internally represented by torch.complex number z.

Parameters:

z (Tensor) – Complex number with the shape of \((B,)\) or \(()\); \((B, 1)\) is read as \((B,)\).

Raises:

TypeCheckError – if z is not a complex tensor (an integer, bool or real floating-point tensor).

Example

>>> real = torch.tensor(0.6)
>>> imag = torch.tensor(0.8)
>>> So2(torch.complex(real, imag)).z
Parameter containing:
tensor(0.6000+0.8000j, requires_grad=True)
__mul__(right)[source]#

Perform a left-multiplication either rotation concatenation or point-transform.

Parameters:

right (So2 | Tensor) – the other So2 transformation, or points of shape \((B, 2)\) or \((2,)\) as a tensor or a Vector2.

Return type:

So2 | Tensor

Returns:

The resulting So2 transformation, or the rotated points with the type of right.

__repr__()[source]#

Return repr(self).

Return type:

str

adjoint()[source]#

Return the adjoint matrix of shape \((B, 2, 2)\).

Return type:

Tensor

Example

>>> s = So2.identity()
>>> s.adjoint()
tensor([[1., -0.],
        [0., 1.]], grad_fn=<StackBackward0>)
static exp(theta)[source]#

Convert elements of lie algebra to elements of lie group.

Parameters:

theta (Tensor) – angle in radians of shape \((B,)\) or \(()\); \((B, 1)\) is squeezed to \((B,)\).

Raises:

TypeCheckError – if theta is bfloat16, which has no complex dtype in PyTorch.

Return type:

So2

Example

>>> v = torch.tensor([3.1415/2])
>>> s = So2.exp(v)
>>> s
Parameter containing:
tensor([4.6329e-05+1.j], requires_grad=True)
classmethod from_matrix(matrix)[source]#

Create So2 from a rotation matrix.

Parameters:

matrix (Tensor) – the rotation matrix to convert of shape \((B, 2, 2)\).

Raises:

TypeCheckError – if matrix is bfloat16, which has no complex dtype in PyTorch.

Return type:

So2

Example

>>> m = torch.eye(2)
>>> s = So2.from_matrix(m)
>>> s.z
Parameter containing:
tensor(1.+0.j, requires_grad=True)
static hat(theta)[source]#

Convert an angle to the so(2) generator \([[0, -\theta], [\theta, 0]]\), which vee() inverts.

The output has shape \((2, 2)\) or \((B, 2, 2)\); a \((B, 1)\) angle is squeezed to \((B,)\). Its matrix exponential is the rotation exp() returns.

Parameters:

theta (Tensor) – angle in radians of shape \((B,)\) or \(()\); \((B, 1)\) is squeezed to \((B,)\).

Return type:

Tensor

Example

>>> theta = torch.tensor(3.1415/2)
>>> So2.hat(theta)
tensor([[ 0.0000, -1.5707],
        [ 1.5707,  0.0000]])
classmethod identity(batch_size=None, device=None, dtype=None)[source]#

Create a So2 group representing an identity rotation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Raises:

TypeCheckError – if dtype is bfloat16, which has no complex dtype in PyTorch.

Return type:

So2

Example

>>> s = So2.identity(batch_size=2)
>>> s
Parameter containing:
tensor([1.+0.j, 1.+0.j], requires_grad=True)
inverse()[source]#

Return the inverse transformation.

Complex-half state is inverted in complex64 and returned in its original dtype.

Return type:

So2

Example

>>> s = So2.identity()
>>> s.inverse().z
tensor(1.+0.j, grad_fn=<MulBackward0>)
log()[source]#

Convert elements of lie group to elements of lie algebra.

Return type:

Tensor

Example

>>> real = torch.tensor([0.6])
>>> imag = torch.tensor([0.8])
>>> So2(torch.complex(real, imag)).log()
tensor([0.9273], grad_fn=<Atan2Backward0>)
matrix()[source]#

Return a matrix of shape z.shape + (2, 2) for each stored complex number.

Return type:

Tensor

Example

>>> s = So2.identity()
>>> m = s.matrix()
>>> m
tensor([[1., -0.],
        [0., 1.]], grad_fn=<StackBackward0>)
classmethod random(batch_size=None, device=None, dtype=None)[source]#

Create a So2 group with a unit rotation whose angle is drawn from \(U[-\pi, \pi)\).

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Raises:

TypeCheckError – if dtype is bfloat16, which has no complex dtype in PyTorch.

Return type:

So2

Example

>>> s = So2.random()
>>> s = So2.random(batch_size=3)
static vee(omega)[source]#

Read the angle back from a hat() matrix of shape \((2, 2)\) or \((B, 2, 2)\).

Returns a scalar or a \((B,)\) vector, respectively.

It reads the [1, 0] entry, \(\theta\) in the so(2) generator \([[0, -\theta], [\theta, 0]]\).

Parameters:

omega (Tensor) – 2x2-matrix built by hat().

Return type:

Tensor

Example

>>> v = torch.ones(3)
>>> omega = So2.hat(v)
>>> So2.vee(omega)
tensor([1., 1., 1.])
property z: Tensor#

Return the underlying complex number of shape \(()\) or \((B,)\).

A \((B, 1)\) z given to the constructor stays stored, and registered, as it was given, and is read here as a \((B,)\) view.

class kornia.geometry.liegroup.Se2(rotation, translation)[source]#

Base class to represent the Se2 group.

The SE(2) is the group of rigid body transformations about the origin of two-dimensional Euclidean space \(R^2\) under the operation of composition.

Convention:
  • matrix() is the 3x3 \([[R, t], [0, 1]]\). a * b is a.matrix() @ b.matrix() and g * p is \(R p + t\), as in Se3, but an unbatched pose also transforms \((N, 2)\) points and a batched one a single \((2,)\) point. The rotation is an So2, whose storage and direction conventions apply.

  • The tangent vector is \((v_x, v_y, \theta)\), angle last: exp rotates by \(\theta\) and translates by \(V(\theta) (v_x, v_y)\), and log returns \(\theta\) in \([-\pi, \pi]\). adjoint() is \([[R, (t_y, -t_x)^\top], [0, 1]]\).

  • from_matrix ignores the bottom row. In eager execution, it checks approximately that the rotation block has the form \([[a, -b], [b, a]]\), a rotation scaled by \(\sqrt{a^2 + b^2}\), and keeps the scale as a non-unit z that log drops; it rejects a reflection. Graph export omits the value check and interprets the block as z = m00 + i m10.

  • t is always a tensor registered as module state, whichever constructor built the pose; a Vector2 passed to the constructor is unwrapped. g * p returns a Vector2 only when p is one.

  • hat returns the se(2) generator \([[0, -\theta, v_x], [\theta, 0, v_y], [0, 0, 0]]\) and vee reads it back, so matrix_exp(hat(v)) equals exp(v).matrix().

  • Module conversions follow So2’s dtype policy for the rotation and PyTorch’s native policy for the translation. A bfloat16 cast changes the translation precision while keeping the rotation’s existing complex precision; both follow any requested device move. Building a pose from bfloat16 values (exp, identity, random, from_matrix or trans*) raises TypeCheckError, as for So2.

Example

>>> so2 = So2.identity(1)
>>> t = torch.ones((1, 2))
>>> se2 = Se2(so2, t)
>>> se2
rotation: Parameter containing:
tensor([1.+0.j], requires_grad=True)
translation: Parameter containing:
tensor([[1., 1.]], requires_grad=True)
__init__(rotation, translation)[source]#

Construct the base class.

Internally represented by a torch.complex number z and a translation 2-vector.

Parameters:
  • rotation (So2) – So2 group encompassing a rotation.

  • translation (Vector2 | Tensor) – translation torch.Tensor with the shape of \((B, 2)\), or a Vector2 wrapping one; the tensor is what gets stored. It must have the rotation’s dtype (z’s real dtype) and device; a bfloat16 translation is also accepted beside a complex32, complex64 or complex128 rotation, which is what .bfloat16() leaves (PyTorch has no complex bfloat16). Every method then reads the translation at the rotation’s precision, and inverse and g * g return a translation of the rotation’s real dtype.

Raises:
  • TypeCheckError – if the translation is an integer, bool or complex tensor (an nn.Parameter too), or its dtype differs from the rotation’s (log and the other methods cannot combine them).

  • DeviceError – if the translation is on another device than the rotation.

Example

>>> so2 = So2.identity(1)
>>> t = torch.ones((1, 2))
>>> se2 = Se2(so2, t)
>>> se2
rotation: Parameter containing:
tensor([1.+0.j], requires_grad=True)
translation: Parameter containing:
tensor([[1., 1.]], requires_grad=True)
__mul__(right)[source]#

Compose two Se2 transformations, or transform points.

Parameters:

right (Se2 | Tensor) – the other Se2 transformation, or points of shape \((B, 2)\) or \((2,)\).

Return type:

Se2 | Tensor

Returns:

The resulting Se2 transformation, or the transformed points.

__repr__()[source]#

Return repr(self).

Return type:

str

adjoint()[source]#

Return the adjoint matrix of shape \((B, 3, 3)\).

Return type:

Tensor

Example

>>> s = Se2.identity()
>>> s.adjoint()
tensor([[1., -0., 0.],
        [0., 1., -0.],
        [0., 0., 1.]], grad_fn=<CopySlices>)
static exp(v)[source]#

Convert elements of lie algebra to elements of lie group.

Parameters:

v (Tensor) – vector of shape \((B, 3)\).

Return type:

Se2

Example

>>> v = torch.ones((1, 3))
>>> s = Se2.exp(v)
>>> s.r
Parameter containing:
tensor([0.5403+0.8415j], requires_grad=True)
>>> s.t
Parameter containing:
tensor([[0.3818, 1.3012]], requires_grad=True)
classmethod from_matrix(matrix)[source]#

Create an Se2 group from a matrix.

Parameters:

matrix (Tensor) – torch.Tensor of shape \((B, 3, 3)\).

Return type:

Se2

Example

>>> s = Se2.from_matrix(torch.eye(3).repeat(2, 1, 1))
>>> s.r
Parameter containing:
tensor([1.+0.j, 1.+0.j], requires_grad=True)
>>> s.t
Parameter containing:
tensor([[0., 0.],
        [0., 0.]], requires_grad=True)
static hat(v)[source]#

Convert a tangent vector to the se(2) generator. Returns v.shape[:-1] + (3, 3).

For \(v = (v_x, v_y, \theta)\) the matrix is \([[0, -\theta, v_x], [\theta, 0, v_y], [0, 0, 0]]\). vee() inverts it, and its matrix exponential is the pose exp() returns.

Parameters:

v (Tensor) – vector of shape \((B, 3)\) or \((3,)\).

Return type:

Tensor

Example

>>> v = torch.tensor([1.0, 2.0, 0.5])
>>> Se2.hat(v)
tensor([[ 0.0000, -0.5000,  1.0000],
        [ 0.5000,  0.0000,  2.0000],
        [ 0.0000,  0.0000,  0.0000]])
classmethod identity(batch_size=None, device=None, dtype=None)[source]#

Create a Se2 group representing an identity rotation and zero translation.

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

Se2

Example

>>> s = Se2.identity(1)
>>> s.r
Parameter containing:
tensor([1.+0.j], requires_grad=True)
>>> s.t
Parameter containing:
tensor([[0., 0.]], requires_grad=True)
inverse()[source]#

Return the inverse transformation.

Return type:

Se2

Example

>>> s = Se2(So2.identity(1), torch.ones(1,2))
>>> s_inv = s.inverse()
>>> s_inv.r
tensor([1.+0.j], grad_fn=<MulBackward0>)
>>> s_inv.t
tensor([[-1., -1.]], grad_fn=<StackBackward0>)
log()[source]#

Convert elements of lie group to elements of lie algebra.

Return type:

Tensor

Example

>>> v = torch.ones((1, 3))
>>> s = Se2.exp(v).log()
>>> s.shape
torch.Size([1, 3])
>>> torch.allclose(s, v)
True
>>> s.requires_grad
True
matrix()[source]#

Return the matrix representation of shape \((B, 3, 3)\).

Return type:

Tensor

Example

>>> s = Se2(So2.identity(1), torch.ones(1, 2))
>>> s.matrix()
tensor([[[1., -0., 1.],
         [0., 1., 1.],
         [0., 0., 1.]]], grad_fn=<CopySlices>)
property r: So2#

Return the underlying rotation(So2).

classmethod random(batch_size=None, device=None, dtype=None)[source]#

Create a Se2 group from So2.random and a translation drawn from \(U[0, 1)\).

Parameters:
  • batch_size (Optional[int], optional) – the batch size of the underlying data. Default: None

  • device (Union[str, device, None], optional) – device to place the result on. Default: None

  • dtype (Optional[dtype], optional) – dtype of the result. Default: None

Return type:

Se2

Example

>>> s = Se2.random()
>>> s = Se2.random(batch_size=3)
property rotation: So2#

Return the underlying rotation(So2).

property so2: So2#

Return the underlying rotation(So2).

property t: Tensor#

Return the underlying translation vector of shape \((B,2)\).

classmethod trans(x, y)[source]#

Construct a translation only Se2 instance.

Parameters:
  • x (Tensor) – the x-axis translation.

  • y (Tensor) – the y-axis translation.

Return type:

Se2

classmethod trans_x(x)[source]#

Construct a x-axis translation.

Parameters:

x (Tensor) – the x-axis translation.

Return type:

Se2

classmethod trans_y(y)[source]#

Construct a y-axis translation.

Parameters:

y (Tensor) – the y-axis translation.

Return type:

Se2

property translation: Tensor#

Return the underlying translation vector of shape \((B,2)\).

static vee(omega)[source]#

Read the tangent vector back from a hat() matrix.

It reads the translation from the last column and the angle from the [1, 0] entry.

Parameters:

omega (Tensor) – 3x3-matrix built by hat(), of shape \((B, 3, 3)\) or \((3, 3)\).

Return type:

Tensor

Returns:

vector of shape \((B, 3)\) or \((3,)\).

Example

>>> v = torch.ones(3)
>>> omega_hat = Se2.hat(v)
>>> Se2.vee(omega_hat)
tensor([1., 1., 1.])