# 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

*2020 IEEE 27th Symposium on Computer Arithmetic (ARITH)*, 48–55. https://doi.org/10.1109/ARITH48897.2020.00016.

*CoRR*. http://arxiv.org/abs/1711.02508v1.

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

*In Practice*7 (1): 1–16. https://doi.org/10.1.1.117.6808.