Numpy¶
The most important part of this package's API is actually numpy's API,
because the quaternion type is added as a possible dtype for numpy
arrays. This means that everything you can do with numpy arrays will
also apply to quaternion arrays.
It can be helpful to think of quaternions as generalized complex
numbers; all the operations that you can do with complex numbers are
also available for quaternions. This includes all the usual
arithmetic operations (addition, subtraction, multiplication,
division, and exponentiation), as well as exponential and logarithmic
functions. Note that it is also possible to convert arrays of
quaternions to and from arrays of floats (with an extra dimension of
size 4), using the from_float_array and as_float_array functions.
Here, we will single out a few of the very most important numpy functions that are particularly useful for quaternions.
numpy.exp(q)¶
This returns the exponential function applied to each quaternion in the array. This is the quaternion analog of the exponential function for complex numbers, and is defined as usual:
$$ \exp(g) = \sum_{n=0}^\infty \frac{g^n}{n!}. $$
The interpretation is that if g is the "generator" of a rotation,
then numpy.exp(g) is the quaternion representation of the
corresponding rotation operator.
import numpy as np
import quaternion
g = quaternion.from_float_array([[0, np.pi/4, 0, 0], [0, 0, np.pi/2, 0]])
R = np.exp(g)
print(R)
Here, g contains two quaternions, which are "generators" of a
rotation about the x-axis and a rotation about the y-axis. The output
is
[quaternion(0.707107, 0.707107, 0, 0)
quaternion(0, 0, 1, 0)]
which represent the same things as unit quaternions.
However, note that these rotations are not by $\pi/4$ and $\pi/2$,
as one might guess by looking at $g$. Rather, they are rotations by
twice those angles, because of the way quaternions represent
rotations. Therefore, $g$ is not the axis-angle representation; it is
half the axis-angle representation. If you wish to convert to or
from axis-angle representation, use the from_rotation_vector and
as_rotation_vector functions instead.
numpy.log(R)¶
The log function is (almost) the inverse of the exp function. In
particular, we can go backwards from the R defined above to get back
to g. If we evaluate
print(np.log(R))
we see that the result is precisely the same as g.
However, just as with the complex logarithm, the quaternion logarithm
is multi-valued, and we must make a choice of branch cut. The log
function always returns the value of the logarithm whose vector part
has magnitude less than or equal to $\pi$. Thus, $\exp(\log(q)) = q$
will always be true, but $\log(\exp(g)) = g$ will only be true if the
vector part of $g$ has magnitude less than or equal to $\pi$.
ndarray.conjugate()¶
Just as with complex numbers and the complex conjugate, the quaternion conjugate is extremely important. This conjugate reverses the sign of the vector part of the quaternion, and is used in many calculations, including finding the inverse and norm of a quaternion, and rotating vectors.
Numpy has two ways of accessing the
conjugate of an array: conj and conjugate. The output of
R.conj() or R.conjugate() is
[quaternion(0.707107, -0.707107, 0, 0)
quaternion(0, 0, -1, 0)]
Note that R * v * R.conj() is a valid way to rotate the pure-vector
quaternion v, but it can be more efficient and accurate to use the
rotate_vectors function instead.