Numpy Array Index Issue - python

I am trying to implement Newtons_method for multivariable scenario. I am trying to output multiple iterations, but am getting an indexing error
import symengine
from symengine import var
import numpy as np
vars =var("x y")
sol=[]
def jacob():
f = ['2*x+y**2-8','x**2-y**2+x*y-3'] # Define function
J = symengine.zeros(len(f),len(vars)) # Initialise Jacobian matrix
# Fill Jacobian matrix with entries
for i, fi in enumerate(f):
for j, s in enumerate(vars):
J[i,j] = symengine.diff(fi, s)
sol.append(J[i,j])
a = np.array([sol[0],sol[1],sol[2],sol[3]])
return a
def eval1(func,val1,val2):
z=[]
for b in func:
b=str(b)
x=val1
y=val2
z.append(eval(b))
return np.array([[z[0],z[1]],[z[2],z[3]]])
def newtons_method(f, df, x0, e):
q=10
while q > e:
q=q-1
x0 = np.absolute(x0 - (np.array([[f(x0[0][0])],[df(x0[1][0])]]))/(eval1(jacob(),x0[0][0],x0[1][0])))
print('Root is at: ', x0)
print('f(x) at root is: ', f(x0))
def f(x):
return 2*x+y**2-8
def df(x):
return x**2-y**2+x*y-3
x0s = np.array([[1],[1]])
for x0 in x0s:
newtons_method(f, df, x0, 1)
I am getting error: invalid index to scalar variable.
Where I set the value to x0 under the newtons_method function, any ideas as to what is going wrong?

When calling newtons_method function, an element of [[1],[1]] i.e. [1] is being passed as parameter x0. Inside the function, x0[0][0] has been used which gives invalid index to scalar variable error.
You should pass x0s as parameter if you want to use both the elements.
x0s = np.array([[1],[1]])
newtons_method(f, df, x0s, 1)

Related

Writing lambda in MATLAB

I am trying to convert this code into MATLAB but I am not sure how to do the subscripts (Y[i] = Y[i-1]) as well as the func and f_exact variables
heres the code:
def Forward_Euler(y0,t0,T,dt,f):
t = np.arange(t0,T+dt,dt)
Y = np.zeros(len(t))
Y[0] = y0
for i in range(1,len(t)):
Y[i] = Y[i-1]+dt*f(Y[i-1], t[i-1])
return Y, t
func = lambda y,t: y-t
f_exact = lambda t: t+1-1/2*np.exp(t)
You can use anonymous functions in matlab:
func = #(y,t)(y - t)
f_exact = #(t)(t + 1 - exp(t)/2) % it works with any matrix t as well
And you can use for matrices as well (they should keep matrix operation rules). For example, in func function, as there is a minus in the form of function, the dimension of y and t must be the same.

Integral with variable limits in python

I'm trying to compute the following integral
using scipy, with the following program:
def E(z):
result = 1/np.sqrt(Om*(1 + z)**3 + Ode + Ox*(1 + z)**2)
return result
def r(z, E):
result, error = quad(E, 0, z) # integrate E(z) from 0 to z
return result
z being the independent variable, while Om Ode and Ox are simply constants (previously assigned).
When I then try to call the function:
z = np.linspace(1e-3, 4, 300)
plt.plot(z, r(z))
I get the error
flip, a, b = b < a, min(a, b), max(a, b)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any()
or a.all()
What is the problem? Is scipy.quad unable to integrate up to a variable?
Thank you so much for your help
You could use a combination of Python's map(function, iterable, ...) function,
Return an iterator that applies function to every item of iterable, yielding the results.
and functools partial(func[,*args][, **keywords]) method:
Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords.
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
from functools import partial
def E(z):
Om = 0.32
Ode = 0.68
Ox = 0
result = 1/np.sqrt(Om*(1 + z)**3 + Ode + Ox*(1 + z)**2)
return result
def r(z):
result = np.array(
list(map(partial(quad, E, 0), z))
)[:, 0] # integrate E(z) from 0 to z
return result
z = np.linspace(1e-3, 4, 300)
fig, ax = plt.subplots()
ax.plot(z, r(z))
fig.show()

Python scipy.optimize.fmin_l_bfgs_b error occurs

My code is to implement an active learning algorithm, using L-BFGS optimization. I want to optimize four parameters: alpha, beta, w and gamma.
However, when I run the code below, I got an error:
optimLogitLBFGS = sp.optimize.fmin_l_bfgs_b(func, x0 = x0, args = (X,Y,Z), fprime = func_grad)
File "C:\Python27\lib\site-packages\scipy\optimize\lbfgsb.py", line 188, in fmin_l_bfgs_b
**opts)
File "C:\Python27\lib\site-packages\scipy\optimize\lbfgsb.py", line 311, in _minimize_lbfgsb
isave, dsave)
_lbfgsb.error: failed in converting 7th argument ``g' of _lbfgsb.setulb to C/Fortran array
0-th dimension must be fixed to 22 but got 4
My code is:
# -*- coding: utf-8 -*-
import numpy as np
import scipy as sp
import scipy.stats as sps
num_labeler = 3
num_instance = 5
X = np.array([[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4],[5,5,5,5]])
Z = np.array([1,0,1,0,1])
Y = np.array([[1,0,1],[0,1,0],[0,0,0],[1,1,1],[1,0,0]])
W = np.array([[1,1,1,1],[2,2,2,2],[3,3,3,3]])
gamma = np.array([1,1,1,1,1])
alpha = np.array([1,1,1,1])
beta = 1
para = np.array([1,1,1,1,1,1,1,1,1,2,2,2,2,3,3,3,3,1,1,1,1,1])
def get_params(para):
# extract parameters from 1D parameter vector
assert len(para) == 22
alpha = para[0:4]
beta = para[4]
W = para[5:17].reshape(3, 4)
gamma = para[17:]
return alpha, beta, gamma, W
def log_p_y_xz(yit,zi,sigmati): #log P(y_it|x_i,z_i)
return np.log(sps.norm(zi,sigmati).pdf(yit))#tested
def log_p_z_x(alpha,beta,xi): #log P(z_i=1|x_i)
return -np.log(1+np.exp(-np.dot(alpha,xi)-beta))#tested
def sigma_eta_ti(xi, w_t, gamma_t): # 1+exp(-w_t x_i -gamma_t)^-1
return 1/(1+np.exp(-np.dot(xi,w_t)-gamma_t)) #tested
def df_alpha(X,Y,Z,W,alpha,beta,gamma):#df/dalpha
return np.sum((2/(1+np.exp(-np.dot(alpha,X[i])-beta))-1)*np.exp(-np.dot(alpha,X[i])-beta)*X[i]/(1+np.exp(-np.dot(alpha,X[i])-beta))**2 for i in range (num_instance))
#tested
def df_beta(X,Y,Z,W,alpha,beta,gamma):#df/dbelta
return np.sum((2/(1+np.exp(-np.dot(alpha,X[i])-beta))-1)*np.exp(-np.dot(alpha,X[i])-beta)/(1+np.exp(-np.dot(alpha,X[i])-beta))**2 for i in range (num_instance))
def df_w(X,Y,Z,W,alpha,beta,gamma):#df/sigma * sigma/dw
return np.sum(np.sum((-3)*(Y[i][t]**2-(-np.log(1+np.exp(-np.dot(alpha,X[i])-beta)))*(2*Y[i][t]-1))*(1/(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))**4)*(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))*(1-(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t]))))*X[i]+(1/(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))**2)*(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))*(1-(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t]))))*X[i]for t in range(num_labeler)) for i in range (num_instance))
def df_gamma(X,Y,Z,W,alpha,beta,gamma):#df/sigma * sigma/dgamma
return np.sum(np.sum((-3)*(Y[i][t]**2-(-np.log(1+np.exp(-np.dot(alpha,X[i])-beta)))*(2*Y[i][t]-1))*(1/(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))**4)*(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))*(1-(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t]))))+(1/(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))**2)*(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t])))*(1-(1/(1+np.exp(-np.dot(X[i],W[t])-gamma[t]))))for t in range(num_labeler)) for i in range (num_instance))
def func(para, *args):
alpha, beta, gamma, W = get_params(para)
#args
X = args [0]
Y = args[1]
Z = args[2]
return np.sum(np.sum(log_p_y_xz(Y[i][t], Z[i], sigma_eta_ti(X[i],W[t],gamma[t]))+log_p_z_x(alpha, beta, X[i]) for t in range(num_labeler)) for i in range (num_instance))
#tested
def func_grad(para, *args):
alpha, beta, gamma, W = get_params(para)
#args
X = args [0]
Y = args[1]
Z = args[2]
#gradiants
d_f_a = df_alpha(X,Y,Z,W,alpha,beta,gamma)
d_f_b = df_beta(X,Y,Z,W,alpha,beta,gamma)
d_f_w = df_w(X,Y,Z,W,alpha,beta,gamma)
d_f_g = df_gamma(X,Y,Z,W,alpha,beta,gamma)
return np.array([d_f_a, d_f_b,d_f_w,d_f_g])
x0 = np.concatenate([np.ravel(alpha), np.ravel(beta), np.ravel(W), np.ravel(gamma)])
optimLogitLBFGS = sp.optimize.fmin_l_bfgs_b(func, x0 = x0, args = (X,Y,Z), fprime = func_grad)
I am not sure what is the problem. Maybe, the func_grad cause the problem? Could anyone have a look? thanks
You need to be taking the derivative of func with respect to each of the elements in your concatenated array of alpha, beta, w, gamma parameters, so func_grad ought to return a single 1D array of the same length as x0 (i.e. 22). Instead it returns a jumble of two arrays and two scalar floats nested inside an np.object array:
In [1]: func_grad(x0, X, Y, Z)
Out[1]:
array([array([ 0.00681272, 0.00681272, 0.00681272, 0.00681272]),
0.006684719133999417,
array([-0.01351227, -0.01351227, -0.01351227, -0.01351227]),
-0.013639910534587798], dtype=object)
Part of the problem is that np.array([d_f_a, d_f_b,d_f_w,d_f_g]) is not concatenating those objects into a single 1D array since some are numpy arrays and some are Python floats. That part is easily solved by using np.hstack([d_f_a, d_f_b,d_f_w,d_f_g]) instead.
However, the combined sizes of these objects is still only 10, whereas the output of func_grad needs to be a 22-long vector. You will need to take another look at your df_* functions. In particular, W is a (3, 4) array, but df_w only returns a (4,) vector, and gamma is a (4,) vector whereas df_gamma only returns a scalar.

ValueError while using scipy.integrate to calculate value of a function

I am trying to evaluate a function for different values of a variable n, I created a np.linspace for this vairiable and plugged it into a function Q:
def Q(z_i, z_min,f_gamma, mDM, sigma_v,n, with_ucmh):
dQdz_z = lambda z : dQdz(f_gamma, mDM, sigma_v, z,n, with_ucmh)
integrand = lambda z: ((1/((1+z)*H_z(z)))* (dQdz_z(z)) * np.exp(-tau(z)))
second_part = const.C*const.B*integrate.romberg(integrand,z_min,z_i)
return second_part
z_i = 2.0e6
z_min = 5.0e4
sigma_v = 3.0e-27
f_gamma = 1.
mDM = 10.
with_ucmh = True
n = np.linspace(1.,1.3,100)
mu = Q(z_i, z_min,f_gamma, mDM, sigma_v,n, with_ucmh)
I get ValueError: setting an array element with a sequence that point me to the line where I use the integrate.romberg method of scipy, but I don't understand how come I get here this sort of error..

having trouble using scipy.optimize.leastsq

everything else works fine but when I use the leasesq function the pydev editor have an error that says Undefined variable from import: leastsq what is going on here?
the code is the MIT's python cost model timing.py at the url: http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/readings/python-cost-model/timing.py
and the leastsq part is in the function:
def fit2(A,b):
""" Relative error minimizer """
def f(x):
assert len(x) == len(A[0])
resids = []
for i in range(len(A)):
sum = 0.0
for j in range(len(A[0])):
sum += A[i][j]*x[j]
relative_error = (sum-b[i])/b[i]
resids.append(relative_error)
return resids
ans = scipy.optimize.leastsq(f,[0.0]*len(A[0]))
# print "ans:",ans
if len(A[0])==1:
x = [ans[0]]
else:
x = ans[0]
resids = sum([r*r for r in f(x)])
return (x,resids,0,0)
It seems to me that you're giving the LSQ-function two keyword arguments, while it requires three. You're supplying it with the function, the initial values, but not with the actual values over which the LSQ is to be made?
Instead of hard-coding the calculation of the residuals try just wrapping the residuals as a function which is the difference between the data values and the function to minimize:
for example, just fitting a gaussian function to some data set:
M = np.array(data) # your data as a Nx2 Matrix of (x, y) data points
initials = [3,2,1] # just some initial guess values
def gaussian(x, p):
return p[0]*np.exp((-(x-p[1])**2.0)/p[2]**2.0) # definition of the function
def residuals(p, y, x):
return y - gaussian(x, p) # definition of the residual
cnsts = leastsq(residuals, initials, args=(M[:,1], M[:,0]))[0] # outputs optimized initials

Categories

Resources