# Creating uniform random quaternion and multiplication of two quaternions

## Question:

I have a python (NumPy) function which creates a uniform random quaternion. I would like to get two quaternion multiplication as 2-dimensional returned array from the same or an another function. The formula of quaternion multiplication in my recent case is Q1*Q2 and Q2*Q1. Here, `Q1=(w0, x0, y0, z0)`

and `Q2=(w1, x1, y1, z1)`

are two quaternions. The expected two quaternion multiplication output (as 2-d returned array) should be

```
return([-x1*x0 - y1*y0 - z1*z0 + w1*w0, x1*w0 + y1*z0 - z1*y0 +
w1*x0, -x1*z0 + y1*w0 + z1*x0 + w1*y0, x1*y0 - y1*x0 + z1*w0 +
w1*z0])
```

Can anyone help me please? My codes are here:

```
def randQ(N):
#Generates a uniform random quaternion
#James J. Kuffner 2004
#A random array 3xN
s = random.rand(3,N)
sigma1 = sqrt(1.0 - s[0])
sigma2 = sqrt(s[0])
theta1 = 2*pi*s[1]
theta2 = 2*pi*s[2]
w = cos(theta2)*sigma2
x = sin(theta1)*sigma1
y = cos(theta1)*sigma1
z = sin(theta2)*sigma2
return array([w, x, y, z])
```

## Answers:

A 2-Dimensional Array is an array like this: foo[0][1]

You don’t need to do that. Multiplying two quaternions yields one single quaternion. I don’t see why you would need a two-dimensional array, or how you would even use one.

Just have a function that takes two arrays as arguments:

```
def multQuat(q1, q2):
```

then return the relevant array.

```
return array([-q2[1] * q1[1], ...])
```

A simple rendition of your request would be:

```
In [70]: def multQ(Q1,Q2):
...: w0,x0,y0,z0 = Q1 # unpack
...: w1,x1,y1,z1 = Q2
...: return([-x1*x0 - y1*y0 - z1*z0 + w1*w0, x1*w0 + y1*z0 - z1*y0 +
...: w1*x0, -x1*z0 + y1*w0 + z1*x0 + w1*y0, x1*y0 - y1*x0 + z1*w0 +
...: w1*z0])
...:
In [72]: multQ(randQ(1),randQ(2))
Out[72]:
[array([-0.37695449, 0.79178506]),
array([-0.38447116, 0.22030199]),
array([ 0.44019022, 0.56496059]),
array([ 0.71855397, 0.07323243])]
```

The result is a list of 4 arrays. Just wrap it in `np.array()`

to get a 2d array:

```
In [73]: M=np.array(_)
In [74]: M
Out[74]:
array([[-0.37695449, 0.79178506],
[-0.38447116, 0.22030199],
[ 0.44019022, 0.56496059],
[ 0.71855397, 0.07323243]])
```

I haven’t tried to understand or clean up your description – just rendering it as working code.

I know the post is pretty old but would like to add a function using the *pyquaternion* library to calculate quaternion multiplication. The quaternion multiplication mentioned in the question is called the *Hamilton* product. You can use it like below…

```
from pyquaternion import Quaternion
q1 = Quaternion()
q2 = Quaternion()
q1_q2 = q1*q2
```

You can find more about this library here http://kieranwynn.github.io/pyquaternion/

I know that the question is old but as I found it interesting, for future reference I herewith write an answer: if no special data type for quaternions is desirable, then a quaternion can be written as a tuple of a real number and a normal vector as an array of floats. Thus, mathematically, based on the process mentioned here, the Hamilton product of two quaternions $hat{q}_1=(w_1,mathbf{v}_1k$ and $hat{q}_2=(w_2,mathbf{v}_2)$ would be:

$$hat{q}_1 hat{q}_2=(w_1 w_2-mathbf{v}^T_1mathbf{v}_2, w_1 mathbf{v}_2+w_2 mathbf{v}_1+mathbf{v}_1times mathbf{v}_2)$$

Sorry for the math notation that cannot be rendered in Stack Overflow.

Thus in numpy:

```
import numpy as np
q1=(w1,v1)
q2=(w2,v2)
q1q2=(w1*w2-np.matmul(v1.T,v2),w1*v2+w2*v1+np.cross(v1,v2))
```

There is a Python module that adds a quaternion dtype to NumPy.

Please check out the documentation for the quaternion module here.

Here is an example from the documentation. It looks native to the usage of NumPy.

```
>>> import numpy as np
>>> import quaternion
>>> np.quaternion(1,0,0,0)
quaternion(1, 0, 0, 0)
>>> q1 = np.quaternion(1,2,3,4)
>>> q2 = np.quaternion(5,6,7,8)
>>> q1 * q2
quaternion(-60, 12, 30, 24)
>>> a = np.array([q1, q2])
>>> a
array([quaternion(1, 2, 3, 4), quaternion(5, 6, 7, 8)], dtype=quaternion)
>>> np.exp(a)
array([quaternion(1.69392, -0.78956, -1.18434, -1.57912),
quaternion(138.909, -25.6861, -29.9671, -34.2481)], dtype=quaternion)
```