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])
Asked By: Biophysics

||

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], ...])
Answered By: dshus

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.

Answered By: hpaulj

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/

Answered By: Manas

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)$$enter image description here

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))
Answered By: Father Geppeto

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)
Answered By: Oleksandr Sapozhnik
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.