Fsolve. Function call not proper aray of floats or mismatch between input and output - scipy-optimize

I have been through the multiple answers available on here and through the scipy documentation but cannot resolve my problem.
I am trying to find the root of my equation and each time I come up with a different error.
def func(x):
return [sgr*(np.exp(-q*(x/p1)**(1/p2))+np.exp(-alpha*(x/p1)**(1/p2))
-np.exp(-(q+alpha)*(x/p1)**(1/p2)))
+sveg*(1-np.exp(-q*(x/p1)**(1/p2)))-sfor]
initialGuess=[0]
root = fsolve(func, initialGuess)
gives "result from function call is not a proper array of floats"
def func(arguments):
x1 = arguments[0]
x2 = arguments[1]
x3 = arguments[0]
x4 = arguments[1]
return [sgr*(np.exp(-q*(x1/p1)**(1/p2))+np.exp(-alpha*(x2/p1)**(1/p2))
-np.exp(-(q+alpha)*(x3/p1)**(1/p2)))
+sveg*(1-np.exp(-q*(x4/p1)**(1/p2)))-sfor]
initialGuess=np.array([0,0,0,0])
root = fsolve(func, initialGuess)
gives "shape should be (4,) but it is (1,)"
and
def func(arguments):
x1 = arguments[0]
x2 = arguments[1]
x3 = arguments[0]
x4 = arguments[1]
return [sgr*(np.exp(-q*(x1/p1)**(1/p2))+np.exp(-alpha*(x2/p1)**(1/p2))
-np.exp(-(q+alpha)*(x3/p1)**(1/p2)))
+sveg*(1-np.exp(-q*(x4/p1)**(1/p2)))-sfor]
initialGuess=np.array([0,0,0,0])
root = root(func, initialGuess, method='lm')
gives "Improper input: N=4 must not exceed M=1"
Is anyone able to assist?
All the other variables have been defined.

For anyone else struggling with this, a colleague proposed including all the variables in the equation to be solved and it has worked.
def func(x, args):
sgr = args[0]#0.04114
q = args[1]#0.077673
p1= args[2]#4.79914
p2= args[3]#1.0158
sveg = args[4]#0.052059
sfor = args[5]#0.0509 #can vary between sveg and sgr
alpha = args[6]#0.46
return sgr*(numpy.exp(-q*(x/p1)**(1/p2))+numpy.exp(-alpha*(x/p1)**(1/p2))-
numpy.exp(-(q+alpha)*(x/p1)**(1/p2)))+sveg*(1-numpy.exp(-q*(x/p1)**.
(1/p2)))-sfor
sgr = 0.06542
q = 0.19782
p1 = 2.67834
p2 = 3.8795
sveg = 0.03962
sfor = 0.0586
alpha = 0.95
params = [sgr, q, p1, p2, sveg, sfor, alpha]
print("With default parameters:")
print(fsolve(func, 100, params)[0])
print("")

Related

Adaptive Runge-Kutta 4 method

I am trying to find the solution of DEQ dy/dx = 10*e^(-88.8888889(x-2)^2) - 0.6y.
Function:
def dydx(x,y):
return -0.6*y + 10*np.exp(-(x-2)**2/(2*.075**2))
Single Step Solution:
def direct(x,y,h):
k1 = dydx(x,y)
k2 = dydx(x+h/2, y+k1*h/2)
k3 = dydx(x+h/2, y+k2*h/2)
k4 = dydx(x+h, y+k3*h)
y = y + (1/6)*(k1+2*k2+2*k3+k4)*h
return y
Double Step Solution:
def halving(x,y,h):
h = h/2
xh = np.zeros(3)
yh = np.zeros(3)
xh[0] = x
yh[0] = y
for j in range(0,2):
k1 = dydx(xh[j],yh[j])
k2 = dydx(xh[j]+h/2, yh[j]+k1*h/2)
k3 = dydx(xh[j]+h/2, yh[j]+k2*h/2)
k4 = dydx(xh[j]+h, yh[j]+k3*h)
yh[j+1] = yh[j] + (1/6)*(k1+2*k2+2*k3+k4)*h
xh[j+1] = xh[j] + h
return yh[2]
Find the adaptive step size 'h'
def adapt(x,y,h):
error = abs(direct(x,y,h)) - abs(halving(x,y,h)) # it checks whether h falls between a range or not
if error <= 0.01 and error >= .001:
return h
elif error > 0.01:
return adapt(x,y,h/2) # if error is large recalling adapt function with h/2
elif error < .001:
return adapt(x,y,2*h) # 2*h if error is small
Main Driver Program
def rk4(xi,yi,h,xlim):
nval = int((xlim-xi)/h)
x = np.zeros(nval+1)
y = np.zeros(nval+1)
x[0] = xi
y[0] = yi
for i in range(0,nval):
h = adapt(x[i],y[i],h)
y[i+1] = direct(x[i],y[i],h)
x[i+1] = x[i] + h
return x,y
Evaluate using
rk4(0,0.5,.1,4)
I am using jupyter notebook. This program crashes. Probably the recursion section. But why? The error should have been within range after a few recursive call?

Unresolved Reference with Variables that have already been defined?

I am working on a program that requires me to use coordinates. I established 4 different values for coordinates RoiX1, RoiY1, RoiX2, and RoiY2. I also have other values that have been defined that return the same message.
Here is the code for the variables I mentioned earlier that returns this message:
RoiX1 = int(db.child("coordinates").child("Xa1").get().val()
RoiY1 = int(db.child("coordinates").child("Ya1").get().val()
RoiX2 = int(db.child("coordinates").child("Xa2").get().val()
RoiY2 = int(db.child("coordinates").child("Ya2").get().val()
PreArea = abs((RoiX1-RoiX2)*(RoiY1-RoiY2))
For the PreArea, every variable in that equation returns Unresolved reference ''
Here is another example block of code:
rects = []
success, img = cap.read()
classIds, confs, bbox = net.detect(img, confThreshold=0.4)
bbox = list(bbox)
confs = list(np.array(confs).reshape(1, -1)[0])
confs = list(map(float, confs))
indicies = cv2.dnn.NMSBoxes(bbox, confs, 0.2, 0.1)
Here is where these messages show up after the above variables:
if len(classIds) != 0:
i = indicies[0][0]
box = bbox[i]
rects.append(box)
object = tracker.update(rects)
X = object[1][0][0]
Y = object[1][0][1]
W = object[1][0][2]
H = object[1][0][3]
X2 = (X + W)
Y2 =(Y + H)
if abs(RoiX1 - X) <= ROI_dif and abs(RoiY1 - Y) <= ROI_dif abs(RoiX2 - X2) <= ROI_dif and abs(RoiY2 - Y2) <= ROI_dif:
Detected_ClassId = classIds[0][0]
After the if statement, all variables mentioned become underlined with the message.
Here, the variable bbox, indicies, and rects and all other variables no matter where, remain unresolved. Any help as to why this may occur in Python is greatly appreciated.

Programming Secant Method into Python

The sum of two numbers is 20. If each number is added to its square root, the product of the two sums is 155.55. Use Secant Method to approximate, to within 10^(-4), the value of the two numbers.
Based on http://campus.murraystate.edu/academic/faculty/wlyle/420/Secant.htm
#inital guess
x1 = 10
x2 = 50
Epsilon = 1e-4
#given function
def func(x):
return abs(x)**0.5 * (abs(x)+20)**0.5 - 155.55
y1 = func(x1)
y2 = func(x2)
#loop max 20 times
for i in range(20):
ans = x2 - y2 * (x2-x1)/(y2-y1)
y3 = func(ans)
print("Try:{}\tx1:{:0.3f}\tx2:{:0.3f}\ty3:{:0.3f}".format(i,x1, x2, y3))
if (abs(y3) < Epsilon):
break
x1, x2 = x2, ans
y1, y2 = y2, y3
print("\n\nThe numbers are: {:0.3f} and {:0.3f}".format(ans, ans+20))
Based on Your Title
This code works well in most of the cases. Taken from Secant Method Using Python (Output Included)
# Defining Function
def f(x):
return x**3 - 5*x - 9
# Implementing Secant Method
def secant(x0,x1,e,N):
print('\n\n*** SECANT METHOD IMPLEMENTATION ***')
step = 1
condition = True
while condition:
if f(x0) == f(x1):
print('Divide by zero error!')
break
x2 = x0 - (x1-x0)*f(x0)/( f(x1) - f(x0) )
print('Iteration-%d, x2 = %0.6f and f(x2) = %0.6f' % (step, x2, f(x2)))
x0 = x1
x1 = x2
step = step + 1
if step > N:
print('Not Convergent!')
break
condition = abs(f(x2)) > e
print('\n Required root is: %0.8f' % x2)
# Input Section
x0 = input('Enter First Guess: ')
x1 = input('Enter Second Guess: ')
e = input('Tolerable Error: ')
N = input('Maximum Step: ')
# Converting x0 and e to float
x0 = float(x0)
x1 = float(x1)
e = float(e)
# Converting N to integer
N = int(N)
#Note: You can combine above three section like this
# x0 = float(input('Enter First Guess: '))
# x1 = float(input('Enter Second Guess: '))
# e = float(input('Tolerable Error: '))
# N = int(input('Maximum Step: '))
# Starting Secant Method
secant(x0,x1,e,N)

PyMC3- Custom theano Op to do numerical integration

I am using PyMC3 for parameter estimation using a particular likelihood function which has to be defined. I googled it and found out that I should use the densitydist method for implementing the user defined likelihood functions but it is not working. How to incorporate a user defined likelihood function in PyMC3 and to find out the maximum a posteriori (MAP) estimate for my model? My code is given below. Here L is the analytic form of my Likelihood function. I have some observational data for the radial velocity(vr) and postion (r) for some objects, which is imported from excel file.
data_ = np.array(pandas.read_excel('aaa.xlsx',header=None))
gamma=3.77;
G = 4.302*10**-6;
rmin = 3.0;
R = 95.7;
vr=data_[:,1];
r= data_[:,0];
h= np.pi;
class integrateOut(theano.Op):
def __init__(self,f,t,t0,tf,*args,**kwargs):
super(integrateOut,self).__init__()
self.f = f
self.t = t
self.t0 = t0
self.tf = tf
def make_node(self,*inputs):
self.fvars=list(inputs)
try:
self.gradF = tt.grad(self.f,self.fvars)
except:
self.gradF = None
return theano.Apply(self,self.fvars,[tt.dscalar().type()])
def perform(self,node, inputs, output_storage):
args = tuple(inputs)
f = theano.function([self.t]+self.fvars,self.f)
output_storage[0][0] = quad(f,self.t0,self.tf,args=args)[0]
def grad(self,inputs,grads):
return [integrateOut(g,self.t,self.t0,self.tf)(*inputs)*grads[0] \
for g in self.gradF]
basic_model = pm.Model()
with basic_model:
M=[]
beta=[]
interval=0.01*10**12
M=pm.Uniform('M',
lower=0.5*10**12,upper=3.50*10**12,transform='interval')
beta=pm.Uniform('beta',lower=2.001,upper=2.999,transform='interval')
gamma=3.77
logp=[]
arr=[]
vnew=[]
rnew=[]
theta = tt.scalar('theta')
beta = tt.scalar('beta')
z = tt.cos(theta)**(2*( (gamma/(beta - 2)) - 3/2) + 3)
intZ = integrateOut(z,theta,-(np.pi)/2,(np.pi)/2)(beta)
gradIntZ = tt.grad(intZ,[beta])
funcIntZ = theano.function([beta],intZ)
funcGradIntZ = theano.function([beta],gradIntZ)
for j in np.arange(0,59,1):
vnew.append(vr[j]+(0.05*vr[j]*float(dm.Decimal(rm.randrange(1,
20))/10)));
rnew.append(r[j]+(0.05*r[j]*float(dm.Decimal(rm.randrange(1,
20))/10)));
vn=np.array(vnew)
rn=np.array(rnew)
for beta in np.arange (2.01,2.99,0.01):
for M in np.arange (0.5,2.50,0.01):
i=np.arange(0,59,1)
q =( gamma/(beta - 2)) - 3/2
B = (G*M*10**12)/((beta -2 )*( R**(3 - beta)))
K = (gamma - 3)/((rmin**(3 - gamma))*funcIntZ(beta)*m.sqrt(2*B))
logp= -np.log(K*((1 -(( 1/(2*B) )*((vn[i]**2)*rn[i]**(beta -
2))))**(q+1))*(rn[i]**(1-gamma +(beta/2))))
arr.append(logp.sum())
def logp_func(rn,vn):
return min(np.array(arr))
logpvar = pm.DensityDist("logpvar", logp_func, observed={"rn": rn,"vn":vn})
start = pm.find_MAP(model=basic_model)
step = pm.Metropolis()
basicmodeltrace = pm.sample(10000, step=step,
start=start,random_seed=1,progressbar=True)
print(pm.summary(basicmodeltrace))
map_estimate = pm.find_MAP(model=basic_model)
print(map_estimate)
I am getting the following error message:
ValueError: Cannot compute test value: input 0 (theta) of Op
Elemwise{cos,no_inplace}(theta) missing default value.
Backtrace when that variable is created:
I am unable to get the output since the numerical integration is not working. I have used custom theano op for numerical integration code which i got from Custom Theano Op to do numerical integration . The integration works if I run it seperately inputting a particular value of beta, but not within the model.
I made a few changes to your code, this still does not work, but I hope it is closer to a solution. Please check this thread, as someone is trying so solve essentially the same problem.
class integrateOut(theano.Op):
def __init__(self, f, t, t0, tf,*args, **kwargs):
super(integrateOut,self).__init__()
self.f = f
self.t = t
self.t0 = t0
self.tf = tf
def make_node(self, *inputs):
self.fvars=list(inputs)
try:
self.gradF = tt.grad(self.f, self.fvars)
except:
self.gradF = None
return theano.Apply(self, self.fvars, [tt.dscalar().type()])
def perform(self,node, inputs, output_storage):
args = tuple(inputs)
f = theano.function([self.t] + self.fvars,self.f)
output_storage[0][0] = quad(f, self.t0, self.tf, args=args)[0]
def grad(self,inputs,grads):
return [integrateOut(g, self.t, self.t0, self.tf)(*inputs)*grads[0] \
for g in self.gradF]
gamma = 3.77
G = 4.302E-6
rmin = 3.0
R = 95.7
vr = data[:,1]
r = data[:,0]
h = np.pi
interval = 1E10
vnew = []
rnew = []
for j in np.arange(0,59,1):
vnew.append(vr[j]+(0.05*vr[j] * float(dm.Decimal(rm.randrange(1, 20))/10)))
rnew.append(r[j]+(0.05*r[j] * float(dm.Decimal(rm.randrange(1, 20))/10)))
vn = np.array(vnew)
rn = np.array(rnew)
def integ(gamma, beta, theta):
z = tt.cos(theta)**(2*((gamma/(beta - 2)) - 3/2) + 3)
return integrateOut(z, theta, -(np.pi)/2, (np.pi)/2)(beta)
with pm.Model() as basic_model:
M = pm.Uniform('M', lower=0.5*10**12, upper=3.50*10**12)
beta = pm.Uniform('beta', lower=2.001, upper=2.999)
theta = pm.Normal('theta', 0, 10**2)
def logp_func(rn,vn):
q = (gamma/(beta - 2)) - 3/2
B = (G*M*1E12) / ((beta -2 )*(R**(3 - beta)))
K = (gamma - 3) / ((rmin**(3 - gamma)) * integ(gamma, beta, theta) * (2*B)**0.5)
logp = - np.log(K*((1 -((1/(2*B))*((vn**2)*rn**(beta -
2))))**(q+1))*(rn**(1-gamma +(beta/2))))
return logp.sum()
logpvar = pm.DensityDist("logpvar", logp_func, observed={"rn": rn,"vn":vn})
start = pm.find_MAP()
#basicmodeltrace = pm.sample()
print(start)

Not able to print the list, how to rectify the errors?

This program is to find the normalization of a vector but I am not able to print the list:
Def function:
def _unit_vector_sample_(vector):
# calculate the magnitude
x = vector[0]
y = vector[1]
z = vector[2]
mag = ((x**2) + (y**2) + (z**2))**(1/2)
# normalize the vector by dividing each component with the magnitude
new_x = x/mag
new_y = y/mag
new_z = z/mag
unit_vector = [new_x, new_y, new_z]
#return unit_vector
Main program:
vector=[2,3,-4]
def _unit_vector_sample_(vector):
print(unit_vector)
How can I rectify the errors?
Try this:
def _unit_vector_sample_(vector):
# calculate the magnitude
x = vector[0]
y = vector[1]
z = vector[2]
mag = ((x**2) + (y**2) + (z**2))**(1/2)
# normalize the vector by dividing each component with the magnitude
new_x = x/mag
new_y = y/mag
new_z = z/mag
unit_vector = [new_x, new_y, new_z]
return unit_vector
vector=[2,3,-4]
print(_unit_vector_sample_(vector))
prints this output:
[0.3713906763541037, 0.5570860145311556, -0.7427813527082074]
You need to declare a return statement in your _unit_vector_sample function. Otherwise your function will run but it cannot give it results back to main.
Alternatively you can do this:
def _unit_vector_sample_(vector):
# calculate the magnitude
x = vector[0]
y = vector[1]
z = vector[2]
mag = ((x**2) + (y**2) + (z**2))**(1/2)
# normalize the vector by dividing each component with the magnitude
new_x = x/mag
new_y = y/mag
new_z = z/mag
unit_vector = [new_x, new_y, new_z]
print(unit_vector)
vector=[2,3,-4]
_unit_vector_sample_(vector)
resulting in the same output being printed:
[0.3713906763541037, 0.5570860145311556, -0.7427813527082074]
Here by calling print in your function the unit_vector gets printed every time the function is run.
Which one to use depends on what you want to do.
Do you also want to assign the outcome of the fuction to a variable in main then use the first solution (and instead of directly printing the outcome of the function assign it to a variable). If this is not required you can use the second option.

Resources