Python scipy optimize fmin from matlab fminsearch error - python

I am converting this matlab function handle to python and am receiving this error (ValueError: setting an array element with a sequence.) in python. I'm pretty new to python sorry if there is an obvious error.
In matlab:
P = [1 1; 6 1; 6 5]
fh = #(x) sqrt(sum((ones(3,1)*x - P).^2, 2))
[x,fval] = fminsearch(#(x) max(fh(x)),[0 0])
In python:
P = np.matrix([[1, 1],[ 6, 1],[ 6, 5]])
fh = lambda x:np.sqrt(sum(np.power((np.ones((3,1))*x - P),2),axis = 0))
xopt = scipy.optimize.fmin(func=fh,x0 = np.matrix([0, 0]))
The code works in matlab but not in python thanks.

In your matlab code, fminsearch is minimizing the max of fh(x). In the Python code, therefore, the func passed to fmin should be the max of fh as well:
import numpy as np
from scipy import optimize
P = np.array([[1, 1],[ 6, 1],[ 6, 5]])
def fh(x):
return np.max(np.sqrt(np.sum((x - P)**2, axis=1)))
xopt = optimize.fmin(func=fh, x0=np.array([0, 0]))
print(xopt)
yields
Optimization terminated successfully.
Current function value: 3.201562
Iterations: 117
Function evaluations: 222
[ 3.50007127 2.99991092]

Related

<lambda>() takes 1 positional argument but 2 were given

I am trying to implement the same Sage code here: find vector center in python, as follows:
import numpy as np
from scipy.optimize import minimize
def norm(x):
return x/np.linalg.norm(x)
vectors = np.array([[1,2,3],[4,5,6],[7,8,9]])
unit_vectors = [np.divide(v,norm(v)) for v in vectors]
constraints = [lambda x: np.dot(x,u)-1 for u in unit_vectors]
target = lambda x: norm(x)
res = minimize(target,[3,3,3],constraints)
But I keep getting the same problem:
TypeError: <lambda>() takes 1 positional argument but 2 were given
I am not a mathematician, I just want to write a code that can find a center of multidimensional vectors. I tried many things to solve the problem but nothing worked.
Thanks.
The algorithm of the answer that you indicate is not written in python, so which obviously can fail, considering the official docs I have implemented the following solution:
import numpy as np
from scipy.optimize import minimize
x0 = 10, 10, 10
vectors = [
np.array([1, 2, 3]),
np.array([1, 0, 2]),
np.array([3, 2, 4]),
np.array([5, 2, -1]),
np.array([1, 1, -1]),
]
unit_vectors = [vector / np.linalg.norm(vector) for vector in vectors]
constraints = [
{"type": "ineq", "fun": lambda x, u=u: (np.dot(x, u) - 1)} for u in unit_vectors
]
target = lambda x: np.linalg.norm(x)
res = minimize(fun=target, x0=x0, constraints=constraints)
print(res.x)
Output:
[1.38118173 0.77831221 0.42744313]

Numpy equivalent code to Octave's pinv(A) (pseudo-inverse)

I'm absolutely pulling my hair out here when trying to port over a matrix calculation from octave to numpy. This is specifically in regards to multivariate regression.
My arbitrary data is as follows where the array 'x' is my input value:
x = [
[1, 1 ,2],
[1, 3 ,4],
[1, 5 ,6],
[1, 7, 8],
[1, 9 ,10],
[1, 11 ,12]]
And 'y' are my output values (simply the sum):
y = [[3],[7],[11],[15],[19],[23]]
In Octave the following code will calculate the correct coefficients (where pinv(A) calculates the Moore-Penrose pseudo-inverse of matrix A):
pinv (x' * x) * x' * y'
In numpy I am performing the following :
x = np.array(x)
y = np.array(y)
x_T = (x.transpose())
x_theta = (inv(np.dot(x_T,x)))
x_theta = np.dot(x_theta,x_T)
x_theta = np.dot(x_theta,y)
However this outputs:
[[-330.5],[36.875],[-3.875]]
Which is obviously incorrect. Presuming I'm just being simple but any help would be appreciated.
Many thanks!
Posting this as an answer so your question doesn't still show up as unanswered - use np.linalg.pinv (pseudo-inverse) where you would use pinv in Octave.

Python Sympy dot with the conjugate not same as norm squared

Why does sympy give false on the second Boolean? It correctly gives true on the first Boolean. I thought this last line would be the definition of the norm.
from sympy import *
eta_1, eta_2, m = 1, 1, 3
theta_1, theta_2 = symbols("theta_1 theta_2", real=True)
sigma_x = Matrix([[0, 1], [1, 0]])
sigma_y = Matrix([[0, -I], [I, 0]])
sigma_z = Matrix([[1, 0], [0, -1]])
H = eta_1*sin(theta_1)*sigma_x + eta_2*sin(theta_2)*sigma_y + (m-eta_1*cos(theta_1)-eta_2*cos(theta_2))*sigma_z
v = H.eigenvects()
l = v[0][0]
v = v[0][2][0]
n_normal = v/v.norm()
print(simplify(n_normal.norm()**2) == 1)
print(simplify(n_normal.dot(n_normal.H)))
print(simplify(n_normal.dot(n_normal.H)) == 1)
I think this has to do with the fact that sympy fails in that
simplify(abs(x**2)-x*conjugate(x))==0
gives false. Is there some other way to go around this problem, another way to define an inner product that does behave correctly. I'm doing some complicated physics calculations for my thesis and I would really like to check my results with sympy.
PS. I'm using sympy version 1.4dev.
Edit: I think the problem is with the fact that simplify doesn't realize that
$2*\cos(\theta_1)*cos(\theta_2) - 6*\cos(\theta_1) - 6*\cos(\theta_2) + 11>0\:.$
If I replace this in $n_normal$ with its absolute value it works. I think it is weird that the norm function does this correctly and the simplify of what essentially should be the norm doesn't.

Numeric integration in numpy

I want to do something quite simple but I'm unable to find it in the depths of numpy. I want to numerically and continuously integrate a function given by its values (not by its formula!). That means I simply want an array which holds the sums of the beginning of the input array. Example:
Input:
[ 4, 3, 5, 8 ]
Output:
[ 4, 7, 12, 20 ] # [ sum(i[0:1]), sum(i[0:2]), sum(i[0:3]), sum(i[0:4]) ]
Sounds pretty straight forward, so I'm hopeful this must be easy with some numpy functionality I'm currently unable to find.
I found stuff like scipy.integrate.quad() but that seems to integrate over a given range (from a to b) and the returns a single value. I need an array as output.
You're looking for numpy.cumsum:
>>> numpy.cumsum([ 4, 3, 5, 8 ])
array([ 4, 7, 12, 20])
You would simply need numpy.cumsum().
import numpy as np
a = np.array([ 4, 3, 5, 8 ])
print np.cumsum(a) # prints [ 4 7 12 20]
You can use quadpy (pip install quadpy), a project of mine, which as opposed to scipy.integrate.quad() does vectorized compution. Provide it with many intervals, and get all the integral values over these intervals back.
import numpy
import quadpy
a = 0.0
b = 3.0
h = 1.0e-2
n = int((b-a) / h)
x0 = numpy.linspace(a, b, num=n, endpoint=False)
x1 = x0 + h
intervals = numpy.stack([x0, x1])
vals = quadpy.line_segment.integrate(
lambda x: numpy.sin(x),
intervals,
quadpy.line_segment.GaussLegendre(5)
)
res = numpy.cumsum(vals)
import matplotlib.pyplot as plt
plt.plot(x1, numpy.sin(x1), label='f')
plt.plot(x1, res, label='F')
plt.legend()
plt.show()
You don't need numpy to get the output. Using standard itertools we get the following:
from itertools import accumulate
a = [4, 3, 5, 8]
*b, = accumulate(a)
print(b)
# [4, 7, 12, 20]

Python odeint, parameter

I'm trying to solve a simple equation: dM/dr = r*p(r) in python.
I have the values of p at certain values of r:
p(0)=1, p(1)=3, p(2)=5, p(3)=7, p(4)=9, p(5)=11.
I tried using the following code but I get the error
The size of the array returned by func (6) does not match the size of
y0 (1).
I think the problem is that I'm not matching the p values with the r values correctly. There should only be one initial condition since I am only trying to solve one equation. Any help would be greatly appreciated.
This is my code:
from scipy import integrate
import numpy as np
r = np.array([0, 1, 2, 3, 4, 5])
p = np.array([1, 3, 5, 7, 9, 11])
def deriv (z, r, data):
M = r*p
return M
init = np.array([0])
soln = integrate.odeint(deriv, init, p, (r,), full_output=True)
print soln
You are seeing this error because the size of init does not match the size of the array returned by deriv().
To solve the problem, change the following line
init = np.array([0])
to
init = np.array([0, 0, 0, 0, 0, 0])
For more examples on using 'odeint', see:
http://scipy-cookbook.readthedocs.org/items/numpy_scipy_ordinary_differential_equations.html
http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.odeint.html

Categories

Resources