# Quaternions: what are they good for?

## A bit of history

Quaternions come from the quest to find more numbers. A bunch of mathematicians from the 19th century were so impressed by the unreasonable effectiveness of complex numbers that they wondered whether the trick could be extended to other structures, notably other \(n\)-tuples of real numbers.

As it turns out, this only works for some values of \(n\), namely 2, 4, and 8. There are profound reasons for this, with connections to various areas of mathematics. If you want to learn more about the historical background of hypercomplex numbers and their properties, I cannot recommend Stillwell’s *Mathematics and Its History* enough (Stillwell 2010).

Here is a quick recap, in case you’d like a quick overview of all the stuff that could reasonably be considered “numbers”.

*Complex numbers* are of the form \(z = a + ib\), with \(a\) and \(b\) real numbers, and \(i\) (the *imaginary unit* defined such that \(i^2 =
-1\). They form a *field*, and have all the nice properties that we can expect of well-behaved numbers, such as:

- Associativity: \((xy)z = x(yz)\)
- Commutativity: \(xy = yx\)

for all complex numbers \(x\), \(y\), and \(z\).

*Quaternions* are an extension of complex numbers, but in *four* dimensions instead of just two. They are of the form \(\mathbf{q} = a +
ib + jc + kd\), where \(i\), \(j\), and \(k\) the imaginary units. They follow a bunch of rules, which are \(i^2 = j^2 = k^2 = ijk = -1\), and \[ ij = -ji = k,\quad jk = -kj = i,\quad \text{and } ki = -ik = j. \]

One thing we can notice straightaway: quaternions are *not commutative!* That is, in general, \(\mathbf{q_1} \mathbf{q_2} \neq
\mathbf{q_2} \mathbf{q_1}\). However, like the complex numbers, they are associative.

Finally, *octonions* are the last members of the club. They can be described with 8 real components. Their imaginary units behave similarly to quaternions imaginary units, with more complicated rules. And furthermore, they are neither commutative nor even associative! (At this point, one wonders whether they deserve the title of number at all.)

And *that’s it!* There is something really strange happening here: we can define something looking like numbers only for dimensions 2, 4, and 8. Not for 3, not for 6, and not for 17. Moreover, we’re losing important properties along the way. Starting from the full, complete, *perfect* structure of the complex numbersYes, as many authors have pointed out, complex numbers are actually the most “complete” numbers. They have all the interesting properties, and fill in the gaps where so-called “real” numbers are failing. You can define any polynomial you want with complex coefficients, they will always have the correct number of roots in the complex numbers.

, we gradually lose the things that make working with numbers easy and intuitive.

## Why are quaternions interesting?

So we can build these kinds of 4- or 8-dimensional numbers. That is fascinating in a way, even if only to answer the more philosophical question of what numbers are, and what their properties mean. But as it turns out, quaternions also have direct applications, notably in Physics.

Indeed, quaternions are extremely useful for representing *rotations*. There are many different ways to represent rotations:

- Euler angles are arguably the most intuitive: it’s just three angles representing yaw, pitch, and roll.
- Rotation matrices are the most natural from a mathematical point of view. Rotations are invertible linear transformation in 3D space, after all, so they should be represented by matrices in \(\mathrm{GL}_3(\mathbb{R})\).

However, both of these representations suffer from serious drawbacks. Euler angles are nice for intuitively understanding what’s going on, and for visualisation. However, even simple operations like applying a rotation to a vector, or composing two rotations, quickly lead to a lot of messy and unnatural computations. As soon as rotations become larger that \(\pi\), you get positions that are ill-defined (and you have to implement a lot of wraparound in \([-\pi,\pi]\) or \([0,2\pi]\)).

Rotation matrices are more straightforward. Composing two rotations and rotating a vector is matrix-matrix or matrix-vector multiplication. However, a \(3\times 3\) matrix contains 9 scalar elements, just to represent an object that is intrinsically 3-dimensional. Because of this, computations can become costly, or even unstable in floating-point representations.

The quaternion is therefore an elegant compromise in space requirements (4 elements) and ease of computations. It is moreover easy and numerically stable to get rotation matrices from quaternions and vice-versa.

From a numerical stability point of view, it is easier to deal with computation errors in the case of quaternions: a renormalized quaternion is always a valid rotation, while it is difficult to correct a matrix that is not orthogonal any more due to rounding errors.

## Unit quaternions and rotations

Rotations are represented by unit quaternions, i.e. quaternions of norm 1: For a complete derivation of quaternion properties and rotation representation, see Solà (2017).

\[ \mathbf{q} = \exp\left((u_x i + u_y j + u_z k) \frac{\theta}{2}\right). \]

This represents a rotation of angle \(\theta\) around the vector \(\mathbf{u} = [u_x\; u_y\; u_z]^T\). The unit quaternion \(\mathbf{q}\) can also be written as

\[ \mathbf{q} = \cos\left(\frac{\theta}{2}\right) + \mathbf{u}\sin\left(\frac{\theta}{2}\right). \]

Composition of rotations is simply the quaternion multiplication. To orient a vector \(\mathbf{x}\) by applying a rotation, we conjugate it by our quaternion \(\mathbf{q}\):

\[ \mathbf{x'} = \mathbf{q} \mathbf{x} \mathbf{q'}, \]

where all products are quaternion multiplications, and the vectors \(\mathbf{x}\) and \(\mathbf{x'}\) are represented as *pure quaternions*, i.e. quaternions whose real part is zero:

\[ \mathbf{x} = x_1 i + x_2 j + x_3 k. \]

The fact that quaternions are not commutative also corresponds directly to the fact that rotations themselves are not commutative.

## Quaternion conventions

People are using various quaternions conventions, depending on their choice of multiplication formula (\(ij = -k\) or \(ij = k\)) and on their choice of representation (real part first or real part last). The case \(ij = k\) and real part first used in this article is called the *Hamilton convention*, whereas the convention where \(ij = -k\) and the real part is last is called the *JPL convention*.As the name suggest, the JPL convention is used mostly by NASA’s Jet Propulsion Laboratory, and by extension in aerospace applications. The Hamilton convention in more frequent in robotics and in the state estimation literature, such as Kalman filtering (Solà 2017).

As always, it is important to clearly define ahead of time what convention is used in your projects, especially if you’re getting inspirations from books and articles. Check if they are all using the same conventions, or hard-to-debug issues may arise!

Wikipedia and especially Solà (2017) contain a very useful reference of the various possible conventions, and where they are used.

## Applications

Quaternions are often the best choice whenever rotation or attitude representations are required. This includes robotics, aerospace engineering, 3D graphics, video games, and so on.

They are of particular use in optimal control or state estimation scenarios: they are often the representation of choice for the attitude of an object in a Kalman filter for instance. For a nice introduction to Kalman filters, see this blog post or the introductory article by Welch and Bishop (2006).

## Software and libraries

When working with quaternions, it may be tiresome to reimplement all the basic functions you might need (composition, conjugation, conversions to and from rotation matrices and Euler angles, and so on). For an overview of efficient floating-point algorithms for manipulating quaternions, see Joldeş and Muller (2020).

Thankfully, quaternions are a very standard part of engineers toolboxes, so many libraries were written for a variety of scientific programming languages.

For Julia (easily the best programming language for this kind of application in my opinion):

- Quaternions.jl, for basic quaternion representation and manipulation,
- Rotations.jl, for representing rotations and operating on them more generally,
- CoordinateTransformations.jl, for a general framework not limited to rotations.

In Python:

- scipy.spatial.transform.Rotation, which has the benefit of being included in SciPy directly,
- numpy-quaternion, for a more feature-complete implementation.

And if you have to work in Matlab, unfortunately the functionality is locked away in the Robotics System Toolbox, or in the Aerospace Toolbox. Use open source software if you can!

## The structure of the group of unit quaternions

As it turns out, quaternions are even more interesting than expected. Not satisfied with representing rotations efficiently, they also have the structure of a Lie group. A Lie group is a structure that combines the properties of a group and of a differentiable manifold, thus allowing to compute derivatives, and solve differential equations, of functions taking quaternion values. Rotation matrices also have a Lie group structure.

Update: I wrote a detailed post on Lie theory!

This is obviously extremely interesting when studying dynamical systems, as these are often modelled as systems of differential equations. Having a way to define rigorously derivatives and uncertainties on quaternions is a very significant result.

## References

Joldeş, M., and J. -M. Muller. 2020. “Algorithms for Manipulating Quaternions in Floating-Point Arithmetic.” In *2020 IEEE 27th Symposium on Computer Arithmetic (ARITH)*, 48–55. https://doi.org/10.1109/ARITH48897.2020.00016.

Solà, Joan. 2017. “Quaternion Kinematics for the Error-State Kalman Filter.” *CoRR*. http://arxiv.org/abs/1711.02508v1.

Stillwell, John. 2010. *Mathematics and Its History*. Undergraduate Texts in Mathematics. Springer. https://doi.org/10.1007/978-1-4419-6053-5.

Welch, Greg, and Gary Bishop. 2006. “An Introduction to the Kalman Filter.” *In Practice* 7 (1): 1–16. https://doi.org/10.1.1.117.6808.