Biophysics
Biophysics

Reputation: 97

Creating uniform random quaternion and multiplication of two quaternions

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])

Upvotes: 3

Views: 2737

Answers (5)

Oleksandr Sapozhnik
Oleksandr Sapozhnik

Reputation: 59

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)

Upvotes: 0

Father Geppeto
Father Geppeto

Reputation: 149

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_1\mathbf{v}_2, w_1 \mathbf{v}_2+w_2 \mathbf{v}_1+\mathbf{v}_1\times \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))

Upvotes: 1

Manas
Manas

Reputation: 958

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/

Upvotes: 0

hpaulj
hpaulj

Reputation: 231605

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.

Upvotes: 0

dshus
dshus

Reputation: 168

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], ...])

Upvotes: 0

Related Questions