Calculate vector gradient without using a Python library - python

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)

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)

sympy.subs cannot substituting a point to array

import sympy
import numpy
from sympy import ordered, Matrix
x1,x2=sympy.symbols('x1 x2')
f=x1**2-x1*x2-4*x1+x2**2-x2
X0=numpy.array([[1],[1]])
v = list(ordered(f.free_symbols))
gradient = lambda f, v: Matrix([f]).jacobian(v)
gradf=sympy.transpose(gradient(f, v))
gradfx0=(gradf.subs([(x1, X0[0]), (x2, X0[1])]))
print(gradfx0)
I want to calculate the gradient of two variable function in a point in python. I define the function and I find the gradient vector of function (grad). Now when I try to substituting X0 to grad, the result is
Matrix([[2*x1 - x2 - 4], [-x1 + 2*x2 - 1]]).
I want the result should be
Matrix([[-3], [0]]).
How to substituting a point to sympy array?
Using .subs and derive_by_array:
from sympy import symbols
from sympy.tensor.array import derive_by_array
x1, x2 = symbols('x1 x2')
f = x1 ** 2 - x1 * x2 + x2 ** 2 - 4 * x1 - x2
grad = derive_by_array(f, (x1, x2))
# = [2*x1 - x2 - 4, -x1 + 2*x2 - 1]
gradx0 = grad.subs({x1: 1, x2: 1})
# = [-3, 0]
If you want to call your point x0 first, then use variable x0:
x0 = (1, 1)
gradx0 = grad.subs(zip((x1,x2), x0))
# = [-3, 0]

How to calculate gradient from function in python - tuple IndexError?

I'm looking to find the gradient, at point x, for the following function:
f(x) = w1 * x1^2 + w2 * x2
My code so far:
def gradient(w1, w2, x):
gradient = w1 * (x[0]**2) + w2 * (x[1]**2)
return gradient
However, this doesn't work for the following e.g
w1 = 5; w2 = 3; x = (1,)
I'm receiving this error:
IndexError: tuple index out of range
Does this mean one of my indices is wrong? I thought a tuple only has two index 0 & 1. Apologies - appreciate this may be a v basic question.
It works for you, you just passed only one value to the tuple, and you need two. If you wanted to pass zero in this way, then this is incorrect. (1,) - > (1, 0)
def gradient(w1, w2, x):
gradient = w1 * (x[0]**2) + w2 * (x[1]**2)
return gradient
w1 = 5
w2 = 3
x = (1,0)
print(gradient(w1,w2,x))
Output:
5

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

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

Categories

Resources