How to multiply two quaternions by python or numpy [duplicate] - python

This question already has answers here:
Creating uniform random quaternion and multiplication of two quaternions
(5 answers)
Closed 6 years ago.
I have two quaternions: Q1= w0, x0, y0, z0 and Q2 = w1, x1, y1, z1. I would like to multiply them by using NumPy or Python function which can return 2-d array. I found some pseudocodes on the internet which is written by Christoph Gohlke to do this kind of multiplication. I tried a lot but failed to apply it. Can anyone help me please to do this kind of multiplication? The pseudocodes are here: `
def quaternion_multiply(quaternion1, quaternion0):
w0, x0, y0, z0 = quaternion0
w1, x1, y1, z1 = quaternion1
return array([-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], dtype=float64)`

Here's a little example using your function:
import numpy as np
import random
def quaternion_multiply(quaternion1, quaternion0):
w0, x0, y0, z0 = quaternion0
w1, x1, y1, z1 = quaternion1
return np.array([-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], dtype=np.float64)
N = 4
for i in range(N):
q1 = np.random.rand(4)
q2 = np.random.rand(4)
q = quaternion_multiply(q1, q2)
print("{0} x {1} = {2}".format(q1, q2, q))

Related

Why am I getting two different answers with quaternion-vector multiplication

I am trying to multiply a quaternion with a vector following the formula q * v * q_conjugate(q) I found in this thread. When I run the following code in Python, I get an output that looks correct. However, when I run the code again I get another output. How can that be?
Hope you can help!
def q_conjugate(q):
w, x, y, z = q
return (w, -x, -y, -z)
def q_mult(q1, q2):
w1, x1, y1, z1 = q1
w2, x2, y2, z2 = q2
w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2
x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2
y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2
z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2
return w, x, y, z
def qv_mult(q1, v1):
return q_mult(q_mult(q1, v1), q_conjugate(q1))[1:]
v = np.array([0.0, -0.118443, -0.412128, 0.006673])
q = np.array([0.921369, 0.027301, 0.049432, -0.384565])
res = qv_mult(q, v)
Output 1: (0.20736419033763884, -0.37378682006270764, 0.03473104416868859)
Output 2: (-0.37553122668322314, -0.2065883731602419, 0.01484188589166425)
Easy answere. Use pyquaternion to rotate the vector. The correct answere should be output 1.
from pyquaternion import Quaternion
Quaternion([0.921369, 0.027301, 0.049432, -0.384565]).conjugate.rotate([-0.122545--0.004102, -0.214168-0.19796, -0.010722--0.017395])

Multivariate curve fit in python

Can somebody please point me in the right direction...
I need to find the parameters a,b,c,d of two functions:
Y1 = ( (a * X1 + b) * p0 + (c * X2 + d) * p1 ) / (a * X1 + b + c * X2 + d)
Y2 = ( (a * X2 + b) * p2 + (c * X2 + d) * p3 ) / (a * X1 + b + c * X2 + d)
X1, X2 (independent variables) and Y1, Y2 (dependent variables) are observations, i.e. one-dimensional arrays with thousands of entries each.
p0, p1, p2, p3 are known constants (scalars).
I successfully solved the problem with the first function only with a curve-fit (see below), but how do i solve the problem for Y1 and Y2 ?
Thank you.
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
X = [X1,X2]
def fitFunc(X, a,b,c,d):
X1, X2 = X
return ((a * X1 + b) * p0 + (c * X2 + d) * p1) / (a * X1 + b + c * X2 + d)
fitPar, fitCov = curve_fit(fitFunc, X, Y1)
print(fitPar)
One way would be to minimize both your functions together using scipy.optimize.minimze. In the example below, a function residual is passed a, b, c, and d as initial guesses. Using these guesses, Y1 and Y2 are evaluated, then the mean squared error is taken using the data and predicted values of respective functions. The error is returned as the mean error of the two functions. The optimized set of parameters is stored in res as res.x.
import numpy as np
from scipy.optimize import minimize
#p0 = ... known
#p1 = ... known
#p2 = ... known
#p3 = ... known
def Y1(X, a,b,c,d):
X1, X2 = X
return ((a * X1 + b) * p0 + (c * X2 + d) * p1) / (a * X1 + b + c * X2 + d)
def Y2(X, a,b,c,d):
X1, X2 = X
return ((a * X1 + b) * p2 + (c * X2 + d) * p3) / (a * X1 + b + c * X2 + d)
X1 = np.array([X1]) # your X1 array
X2 = np.array([X2]) # your X2 array
X = np.array([X1, X2])
y1_data = np.array([y1_data]) # your y1 data
y2_data = np.array([y2_data]) # your y2 data
def residual(x):
a = x[0]
b = x[1]
c = x[2]
d = x[3]
y1_pred = Y1(X,a,b,c,d)
y2_pred = Y2(X,a,b,c,d)
err1 = np.mean((y1_data - y1_pred)**2)
err2 = np.mean((y2_data - y2_pred)**2)
error = (err1 + err2) / 2
return error
x0 = [1, 1, 1, 1] # Initial guess for a, b, c, and d respectively
res = minimize(residual, x0, method="Nelder-Mead")
print(res.x)

Calculate vector gradient without using a Python library

I am trying to find the gradient of the function
f(x) = w1 * x1^2 + w2 * x2
where x is a vector coordinate (x1,x2).
def gradient(w1, w2, x):
x= (x1,x2)
gradx1=2*w1*x1 + w2 * x2
gradx2= w2 + w1 * x1^2
return (gradx1, gradx2)
My code is coming up with a nameError, saying x1 is not defined when calling the function:
gradient(5, 6, (10,10))
First things first:
x1, x2 = x # unpack your coord tuple
And secondly:
gradx2= w2 + w1 * x1 ** 2 # or gradx2= w2 + w1 * x1 * x1
in python ^ is bitwise XOR. Exponentiation is **.
x is a tuple which you need to unpack like so:
x1, x2 = x
Rather than:
x = (x1, x2)

RK4 Python Explanation

I'd like to use an implementation of RK4 I found online for something, but I'm having a bit of difficulty wrapping my head around the implementations I have found online.
For example:
def rk4(f, x0, y0, x1, n):
vx = [0] * (n + 1)
vy = [0] * (n + 1)
h = (x1 - x0) / float(n)
vx[0] = x = x0
vy[0] = y = y0
for i in range(1, n + 1):
k1 = h * f(x, y)
k2 = h * f(x + 0.5 * h, y + 0.5 * k1)
k3 = h * f(x + 0.5 * h, y + 0.5 * k2)
k4 = h * f(x + h, y + k3)
vx[i] = x = x0 + i * h
vy[i] = y = y + (k1 + k2 + k2 + k3 + k3 + k4) / 6
return vx, vy
Could someone please help me understand what exactly the parameters are? If possible, I'd like a more general explanation, but, if being more specific makes it easier to explain, I'm going to be using it specifically for an ideal spring system.
You are asking for the parameters here:
def rk4(f, x0, y0, x1, n):
...
return vx, vy
f is the ODE function, declared as def f(x,y) for the differential equation y'(x)=f(x,y(x)),
(x0,y0) is the initial point and value,
x1 is the end of the integration interval [x0,x1]
n is the number of sub-intervals or integration steps
vx,vx are the computed sample points, vy[k] approximates y(vx[k]).
You can not use this for the spring system, as that code only works for a scalar v. You would need to change it to work with numpy for vector operations.
def rk4(func, x0, y0, x1, n):
y0 = np.array(y0)
f = lambda x,y: np.array(func(x,y))
vx = [0] * (n + 1)
vy = np.zeros( (n + 1,)+y0.shape)
h = (x1 - x0) / float(n)
vx[0] = x = x0
vy[0] = y = y0[:]
for i in range(1, n + 1):
k1 = h * f(x, y)
k2 = h * f(x + 0.5 * h, y + 0.5 * k1)
k3 = h * f(x + 0.5 * h, y + 0.5 * k2)
k4 = h * f(x + h, y + k3)
vx[i] = x = x0 + i * h
vy[i] = y = y + (k1 + 2*(k2 + k3) + k4) / 6
return vx, vy

Sympy algebraic solution to series summation

I am trying to solve for C in the following equation
I can do this with sympy for an enumrated number of x's, e.g x0, x2, ..., x4 but cannot seem to figure out how to do this for i=0 to t. E.g. for a limited number
from sympy import summation, symbols, solve
x0, x1, x2, x3, x4, alpha, C = symbols('x0, x1, x2, x3, x4, alpha, C')
e1 = ((x0 + alpha * x1 + alpha**(2) * x2 + alpha**(3) * x3 + alpha**(4) * x4)
/ (1 + alpha + alpha**(2) + alpha**(3) + alpha**(4)))
e2 = (x3 + alpha * x4) / (1 + alpha)
rhs = (x0 + alpha * x1 + alpha**(2) * x2) / (1 + alpha + alpha**(2))
soln_C = solve(e1 - C*e2 - rhs, C)
Any insight would be much appreciated.
Thanks to #bryans for pointing me in the direction of Sum. Elaborating on his comment, here is one solution that seems to work. As I am fairly new to sympy if anyone has a more concise approach please share.
from sympy import summation, symbols, solve, Function, Sum
alpha, C, t, i = symbols('alpha, C, t, i')
x = Function('x')
s1 = Sum(alpha**i * x(t-i), (i, 0, t)) / Sum(alpha**i, (i, 0, t))
s2 = Sum(alpha**i * x(t-3-i), (i, 0, t-3)) / Sum(alpha**i, (i, 0, t-3))
rhs = (x(0) + alpha * x(1) + alpha**(2) * x(2)) / (1 + alpha + alpha**(2))
soln_C = solve(s1 - C*s2 - rhs, C)
I'm not sure if this can be catalogued as more "concise", but it could be useful too, when you know the upper limit of the summatory. Let's suppose that we want to evaluate this expression:
We can express it, and solve it, in sympy as follows:
from sympy import init_session
init_session(use_latex=True)
n = 4
As = symbols('A_1:' + str(n+1))
x = symbols('x')
exp = 0
for i in range(n):
exp += As[i]/(1+x)**(i+1)
Ec = Eq(exp,0)
sol = solve(Ec,x)
#print(sol)
#sol #Or, if you're working on jupyter...

Categories

Resources