jaxtransform3d.rotations.robust_polar_decomposition#

jaxtransform3d.rotations.robust_polar_decomposition(A: Array | ndarray | bool_ | number | bool | int | float | complex, n_iter: int = 20, eps: float = 1e-08) Array[source]#

Orthonormalize rotation matrix with robust polar decomposition.

Robust polar decomposition [1] [2] is a computationally more costly method, but it spreads the error more evenly between the basis vectors in comparison to Gram-Schmidt orthonormalization (as in norm_matrix()).

Robust polar decomposition finds an orthonormal matrix that minimizes the Frobenius norm

\[||\boldsymbol{A} - \boldsymbol{R}||^2\]

between the input \(\boldsymbol{A}\) that is not orthonormal and the output \(\boldsymbol{R}\) that is orthonormal.

Parameters:
Aarray-like, shape (3, 3)

Matrix that contains a basis vector in each column. The basis does not have to be orthonormal.

n_iterint, optional (default: 20)

Maximum number of iterations for which we refine the estimation of the rotation matrix.

epsfloat, optional (default: 1e-8)

Precision for termination criterion of iterative refinement.

Returns:
Rarray, shape (3, 3)

Orthonormalized rotation matrix.

See also

norm_matrix

The cheaper default orthonormalization method that uses Gram-Schmidt orthonormalization optimized for 3 dimensions.

References

[1]

Selstad, J. (2019). Orthonormalization. https://zalo.github.io/blog/polar-decomposition/

[2]

Müller, M., Bender, J., Chentanez, N., Macklin, M. (2016). A Robust Method to Extract the Rotational Part of Deformations. In MIG ‘16: Proceedings of the 9th International Conference on Motion in Games, pp. 55-60, doi: 10.1145/2994258.2994269.

Examples

>>> import jax.numpy as jnp
>>> from jaxtransform3d.rotations import robust_polar_decomposition
>>> robust_polar_decomposition(
...     jnp.array([[0.5, 0., 0.], [0., 0.5, 0.], [0., 0., 0.5]]))
Array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)