Python scipy minimize "numpy.float64 object is not callable - python

I have been trying to get over this error for a while and can't quite find a way to fix it. I'm trying to minimize a function, but whenever I call it I get the error in the title. I've looked at several other posts and have tried several different tactics, but no dice. here's the snippet in question here:
def objective_func(a, x_sum,y_sum):
alpha_sum = np.sum(a)
alpha_dot_sum= np.sum(np.dot(a[i],a[j]) for i in range(len(a)) for j in range(len(a)))
return (1/2) * (x_sum*y_sum*alpha_dot_sum)-alpha_sum
def Dual_SVM(data,c,a):
inputs = []
for example in data:
inputs.append(example[0:5])
outputs = []
for example in data:
outputs.append(example[len(example)-1])
bound = [(0,c)]
cons_function = np.sum(a*outputs)
cons = ({'type':'eq','fun':cons_function})
# inputs = []
x_sum= np.sum(np.dot(inputs[i],inputs[j]) for i in range(len(inputs)) for j in range(len(inputs)))
y_sum= np.sum(np.dot(outputs[i],outputs[j]) for i in range(len(outputs)) for j in range(len(outputs)))
sol = minimize(objective_func,x0=a,args=(x_sum,y_sum,),method='SLSQP',constraints=cons,bounds=bound)
return sol
Any feedback on this would be greatly appreciated. I know that the first argument needs to be a function and not just a function call, but I feel like I'm following the proper syntax. Not sure what to do here.

Fixed it. The problem was that cons_function was returning as a float, and not a function. A lambda function in its place fixed the problem.

Related

How to fix attribute Error in Pyomo model python

I am trying to write a pyomo model in python3, but I am facing this error that I can't seem to figure out - 'list' object has no attribute 'is_expression_type'. Below is my pyomo model, any help would be appreciated.
R_avg_tolist = [[0.00043159478649482775,
0.00045388639592182584,
0.0006735271301199177,
0.00044026758948786,
0.0037176592984565836]]
Cov_list = [[5.884677519869241e-05,
5.756542207262417e-05,
6.017027849080026e-05,
6.180151597797322e-05,
-0.0005074353586106837],
[5.756542207262417e-05,
6.0380562653096757e-05,
6.613608499966434e-05,
6.737370769879904e-05,
-0.0005362752804115953],
[6.017027849080026e-05,
6.613608499966434e-05,
8.206495000024503e-05,
8.01694525889321e-05,
-0.0005958716888916681],
[6.180151597797322e-05,
6.737370769879904e-05,
8.01694525889321e-05,
0.00010129901491226823,
-0.000608829853150321],
[-0.0005074353586106837,
-0.0005362752804115953,
-0.0005958716888916681,
-0.000608829853150321,
0.007373689071617548]]
import pyomo.environ as pyo
# Optimization Problem
def create_model(rho,R_avg,Cov):
m = pyo.ConcreteModel()
init_x = {}
m.idx = pyo.Set(initialize=[0,1,2,3,4])
for i in m.idx:
init_x[i] = 0
m.x = pyo.Var(m.idx,initialize=init_x,bounds=(0,None))
def Obj_func(m):
b = []
mult_result = 0
for i in m.idx:
a = 0
for j in m.idx:
a+= m.x[j]*Cov[j][i]
b.append(a)
for i in m.idx:
mult_result += b[i]*m.x[i]
return mult_result
m.OBJ = pyo.Objective(rule=Obj_func)
def constraint1(m):
sum=0
for i in m.idx:
sum+=m.x[i]
return sum ==100
m.C1 = pyo.Constraint(rule=constraint1(m))
def constraint2(m):
sum=0
for i in m.idx:
sum += R_avg_tolist[i]*m.x[i]
return sum >=0.08
m.C2 = pyo.Constraint(rule=constraint2(m))
return m
When I run model using below code, I face the attribute error - 'list' object has no attribute 'is_expression_type'.
rho = 0.0008
model1 = create_model(rho,R_avg_tolist,Cov_list)
solver = SolverFactory('ipopt')
results = solver.solve(model1, tee = True)
Probably not what you want to hear, but your model has many syntax probs. It's obviously a course assignment... Do you have somebody (instructor/TA) to go over this with who can advise a bit?
You didn't include enough info about which line of code caused the issue, but there are several problem areas. I've posted many simple pyomo examples if you scan through some of them, you'll get some ideas, along with the documentation and whatever you have from your course notes....
A few pointers may help:
Do NOT overwrite keywords/functions by using them as variables. When you write:
sum = 0
sum ....
you are nuking the python function sum by making that name a variable and assigning it the value of 0. You should be using sum in several of your functions with verbiage like:
sum(m.X[i] for i in m.idx) # or similar
You seem to be confused on making valid pyomo expressions. That is the core job of pyomo ... to make expressions and fill the model. For example, in your constraint1, you can just make an expression (without a function) and add it to your model. You can do a 1-liner there because the constraint is not a "for each". You could:
m.C1 = pyo.Constraint(expr=sum(m.x[i] for x in m.idx) == 100)
In general, when you are starting:
Add 1 thing to your model, and then print the model:
model.pprint()
See if it looks right, if not, fix it. Then repeat!

Python Error: "divide by zero encountered in log" in function, how to adjust? (Beginner here)

For my current assignment, I am to establish the stability of intersection/equilibrium points between two nullclines, which I have defined as follows:
def fNullcline(F):
P = (1/k)*((1/beta)*np.log(F/(1-F))-c*F+v)
return P
def pNullcline(P):
F = (1/delta)*(pD-alpha*P+(r*P**2)/(m**2+P**2))
return F
I also have a method "stability" that applies the Hurwitz criteria on the underlying system's Jacobian:
def dPdt(P,F):
return pD-delta*F-alpha*P+(r*P**2)/(m**2+P**2)
def dFdt(P,F):
return s*(1/(1+sym.exp(-beta*(-v+c*F+k*P)))-F)
def stability(P,F):
x = sym.Symbol('x')
ax = sym.diff(dPdt(x, F),x)
ddx = sym.lambdify(x, ax)
a = ddx(P)
# shortening the code here: the same happens for b, c, d
matrix = [[a, b],[c,d]]
eigenvalues, eigenvectors = np.linalg.eig(matrix)
e1 = eigenvalues[0]
e2 = eigenvalues[1]
if(e1 >= 0 or e2 >= 0):
return 0
else:
return 1
The solution I was looking for was later provided. Basically, values became too small! So this code was added to make sure no too small values are being used for checking the stability:
set={0}
for j in range(1,210):
for i in range(1,410):
x=i*0.005
y=j*0.005
x,y=fsolve(System,[x,y])
nexist=1
for i in set:
if(abs(y-i))<0.00001:
nexist=0
if(nexist):
set.add(y)
set.discard(0)
I'm still pretty new to coding so the function in and on itself is still a bit of a mystery to me, but it eventually helped in making the little program run smoothly :) I would again like to express gratitude for all the help I have received on this question. Below, there are still some helpful comments, which is why I will leave this question up in case anyone might run into this problem in the future, and can find a solution thanks to this thread.
After a bit of back and forth, I came to realise that to avoid the log to use unwanted values, I can instead define set as an array:
set = np.arange(0, 2, 0.001)
I get a list of values within this array as output, complete with their according stabilities. This is not a perfect solution as I still get runtime errors (in fact, I now get... three error messages), but I got what I wanted out of it, so I'm counting that as a win?
Edit: I am further elaborating on this in the original post to improve the documentation, however, I would like to point out again here that this solution does not seem to be working, after all. I was too hasty! I apologise for the confusion. It's a very rocky road for me. The correct solution has since been provided, and is documented in the original question.

How to call Python function in Pyomo

I have a python function which in turn has many other forton/c++ dlls calling to generate the output value. Now I want to call that function in Pyomo model as expression. Any help on that?
The example I have is:
def mult(a,b):
c = a * b
return(c)
model.a = Var(initialize=1)
model.y = Param(initialize = 6)
def add(model):
x = mult(value(model.a),3)
return(x)
model.value1 = Expression(rule=add)
modelinit_cond1 = Constraint(expr=(model.value1 == model.y))
opt = SolverFactory('ipopt');
results = opt.solve(model, tee=True)
results.write()
Expectation is; ipopt would try finding the value of model.a given that the constraint is satisfied.
Note: The code above is simpler in order simplify the explanation but the real problem on similar grounds.
Many Thanks for help in advance.

Minimize ‖Ax−b‖ (how to write function to use with scipy.optimize.fmin() )

I am trying to minimize ‖Ax−b‖ through the scipy.optimize.fmin function. The data we use is:
A = np.row_stack([[1,1,2],[1,2,1],[2,1,1],[2,2,1]])
B = np.row_stack([[1],[-1],[1],[-1]])
x is found by x=(AtA)^(−1)Atb, and below is my code for this task.
def find_x(A,B):
At = np.transpose(A) # Transpose A
AtA = np.matmul(At, A) # Multiply A with At
return np.matmul(np.matmul(np.linalg.inv(AtA),At),B)
The assigntment says that I should compare this result with the result of scipy.optimize.fmin(), and from what I have read I need a object/ function for fmin to solve. But I don't really get how I would write the code for that function without it containing x, which is the vector I want to find through the optimization.
I've tried to do the basic thing of defining a function like this:
def f(x):
k = np.subtract(np.matmul(A, x), B)
return np.linalg.norm(k)
And the run it through:
def fmin(x0):
return scipy.optimize.fmin(f(x),x0)
where x0 is some initial guess (same shape as the result from find_x), but I only get a error message "'numpy.float64' object is not callable"

Python: Function doesn't receive a value within a for loop

I'm using the bisection method from the scipy.optimize package within a for loop.
The idea is to get a value of "sig" with the bisection method for each element (value) in the "eps_komp" vector. I've coded this much:
import numpy as np
import scipy.optimize as optimize
K=300
n = 0.43
E = 210000
Rm = 700
sig_a = []
RO_K = 300
RO_n = 0.43
eps_komp = [0.00012893048999999997,
0.018839115269999998,
0.01230539995,
0.022996934109999999,
-0.0037319012899999999,
0.023293921169999999,
0.0036927752099999997,
0.020621037629999998,
0.0063656587500000002,
0.020324050569999998,
-0.0025439530500000001,
0.018542128209999998,
0.01230539995,
0.019730076449999998,
0.0045837363899999999,
0.015275270549999997,
-0.0040288883499999999,
0.021215011749999999,
-0.0031379271699999997,
0.023590908229999999]
def eps_f(i):
return eps_komp[i]
for j in range(len(eps_komp)):
eps_komp_j = eps_f(j)
if j <= len(eps_komp):
def func(sig):
return eps_komp_j - sig/E - (sig/RO_K)**(1/RO_n)
sig_a.append(optimize.bisect(func, 0, Rm))
else:
break
print(sig_a)
Now if I change the the value of "j" in eps_f(j) to 0:
eps_komp_j = eps_f(0)
it works, and so it does for all other values that I insert by hand, but if I keep it like it is in the for loop, the "j" value doesnt change automatically and I get an error:
f(a) and f(b) must have different signs
Has anyone a clue what is the problem and how could this be solved?
Regards,
L
P.S. I did post another topic on this problem yesterday, but I wasnt very specific with the problem and got negative feedback. However, I do need to solve this today, so I was forced to post it again, however I did manage to get a bit further with the code then I did in the earlier post, so it isn't a repost...
If you read the docs you'll find that:
Basic bisection routine to find a zero of the function f between the arguments a and b. f(a) and f(b) cannot have the same signs. Slow but sure.
In your code:
def func(sig):
return eps_komp_j - sig/Emod - (sig/RO_K)**(1/RO_n)
sig_a.append(optimize.bisect(func, 0, Rm))
You're passing it func(0) and func(700).
By replacing the optimize.bisect line with print(func(0), func(700)) I get the following output:
0.00012893048999999997 -7.177181168628421
0.018839115269999998 -7.158470983848421
0.01230539995 -7.165004699168421
0.02299693411 -7.15431316500842
-0.00373190129 -7.1810420004084206
0.02329392117 -7.154016177948421
0.0036927752099999997 -7.173617323908421
0.02062103763 -7.156689061488421
0.00636565875 -7.17094444036842
0.02032405057 -7.156986048548421
-0.00254395305 -7.17985405216842
0.018542128209999998 -7.15876797090842
0.01230539995 -7.165004699168421
0.019730076449999998 -7.157580022668421
0.00458373639 -7.172726362728421
0.015275270549999997 -7.162034828568421
-0.00402888835 -7.181338987468421
0.02121501175 -7.156095087368421
-0.0031379271699999997 -7.1804480262884205
0.02359090823 -7.153719190888421
Note the multiple pairs that have the same signs. optimize.bisect can't handle those. I don't know what you're trying to accomplish, but this is the wrong approach.

Categories