Related
I new to python. i was wring a transportation problem solving.when i called out Pulpi, it was caught error
from pulp import LpProblem, LpVariable, LpStatus, LpMinimize, GLPK, value
M = 3
N = 5
a = range(1,M+1)
a1 = range(M)
b = range(1,N+1)
b1 = range(N)
xindx = [(a[i],b[j]) for j in b1 for i in a1]
model = LpProblem("Transportation_LP_Problem",LpMinimize)
x = LpVariable.dicts("X",xindx,0,None)
model += 2190 * x[1,1] + 46650 * x[1,2] + 25110 * x[1,3] + 8040 * x[1,4] + 6720 * x[1,5] \
+ 1800*x[2,1] + 24600 * x[2,2] + 50610 * x[2,3] + 46200 * x[2,4] + 57780 * x[2,5] \
+ 1500*x[3,1] + 45960 * x[3,2] + 24420 * x[3,3] + 7350 * x[3,4] + 6030 * x[3,5],"Transportation_cost"
model += x[1,1] + x[1,2] + x[1,3] + x[1,4] + x[1,5] <= 300.0, "Supply_Pt_1"
model += x[2,1] + x[2,2] + x[2,3] + x[2,4] + x[2,5] <= 260.0, "Supply_Pt_2"
model += x[3,1] + x[3,2] + x[3,3] + x[3,4] + x[3,5] <= 258.0, "Supply_Pt_3"
model += x[1,1] + x[2,1] + x[3,1] >= 200.0, "Demand_Pt_1"
model += x[1,2] + x[2,2] + x[3,2] >= 100.0, "Demand_Pt_2"
model += x[1,3] + x[2,3] + x[3,3] >= 250.0, "Demand_Pt_3"
model += x[1,4] + x[2,4] + x[3,4] >= 185.0, "Demand_Pt_4"
model += x[1,5] + x[2,5] + x[3,5] >= 100.0, "Demand_Pt_5"
model.solve(GLPK())
print ("Status:",LpStatus[model.status])
for v in model.variables():
print(v.name,"=",v.varValue)
print ("Objective Function", value(model.objective))
<model.solve(GLPK())> this is where the error came in
in actualSolve
raise PulpSolverError("PuLP: cannot execute " + self.path)
pulp.apis.core.PulpSolverError: PuLP: cannot execute glpsol.exe
how can i install glpsol.exe or fix this
Install the glpk-utils and try again.
https://winglpk.sourceforge.net/
I have a function with different parameters that I want to optimize to fit some existing data.
The function runs fine on its own, but when I try to pass it through the scipy.optimize.curve_fit function, I get this error :
IndexError: invalid index to scalar variable.
I don't understand why the function would work on its own, and I would not get any errors.
What can I do ?
The original function used dictionnaries and I thought that might be the problem but I modified it and it still doesn't work.
This is the function I'm using :
def function_test(xy,X1,X2,X3,X4):
precip = xy\[0\]
potential_evap = xy\[1\]
nUH1 = int(math.ceil(X4))
nUH2 = int(math.ceil(2.0*X4))
uh1_ordinates = [0] * nUH1
uh2_ordinates = [0] * nUH2
UH1 = [0] * nUH1
UH2 = [0] * nUH2
for t in range(1, nUH1 + 1):
uh1_ordinates[t - 1] = s_curves1(t, X4) - s_curves1(t-1, X4)
for t in range(1, nUH2 + 1):
uh2_ordinates[t - 1] = s_curves2(t, X4) - s_curves2(t-1, X4)
production_store = X1*0.60# S
routing_store = X3*0.70# R
qsim = []
for j in range(2191):
if precip[j] > potential_evap[j]:
net_evap = 0
scaled_net_precip = (precip[j] - potential_evap[j])/X1
if scaled_net_precip > 13:
scaled_net_precip = 13.
tanh_scaled_net_precip = tanh(scaled_net_precip)
reservoir_production = (X1 * (1 - (production_store/X1)**2) * tanh_scaled_net_precip) / (1 + production_store/X1 * tanh_scaled_net_precip)
routing_pattern = precip[j]-potential_evap[j]-reservoir_production
else:
scaled_net_evap = (potential_evap[j] - precip[j])/X1
if scaled_net_evap > 13:
scaled_net_evap = 13.
tanh_scaled_net_evap = tanh(scaled_net_evap)
ps_div_x1 = (2 - production_store/X1) * tanh_scaled_net_evap
net_evap = production_store * (ps_div_x1) / \
(1 + (1 - production_store/X1) * tanh_scaled_net_evap)
reservoir_production = 0
routing_pattern = 0
production_store = production_store - net_evap + reservoir_production
percolation = production_store / (1 + (production_store/2.25/X1)**4)**0.25
routing_pattern = routing_pattern + (production_store-percolation)
production_store = percolation
for i in range(0, len(UH1) - 1):
UH1[i] = UH1[i+1] + uh1_ordinates[i]*routing_pattern
UH1[-1] = uh1_ordinates[-1] * routing_pattern
for j in range(0, len(UH2) - 1):
UH2[j] = UH2[j+1] + uh2_ordinates[j]*routing_pattern
UH2[-1] = uh2_ordinates[-1] * routing_pattern
groundwater_exchange = X2 * (routing_store / X3)**3.5
routing_store = max(0, routing_store + UH1[0] * 0.9 + groundwater_exchange)
R2 = routing_store / (1 + (routing_store / X3)**4)**0.25
QR = routing_store - R2
routing_store = R2
QD = max(0, UH2[0]*0.1+groundwater_exchange)
Q = QR + QD
qsim.append(Q)
return qsim
I'm using if else statements in Jupiter notebook to vary the value of parameters which are then used in a series of differential equations. This is my current set up...
def epsilon1(t, V1, E_v1, I_v1, A_v1, R_v1, N1):
if t < 28:
return 0
if 29 < t < 84:
return 0.006 * N1 / (N1 - (V1 + E_v1 + I_v1 + A_v1 + R_v1))
if 85 < t < 105:
return 0.001 * N1 / (N1 - (V1 + E_v1 + I_v1 + A_v1 + R_v1))
if t > 104:
return 0
if V1 + E_v1 + I_v1 + A_v1 + R_v1 > 0.4 * N1:
return 0
Then I set up my differential equations as follows:
def deriv(y, t, N...
Lambda1 = beta11 * (I_s1 + delta_a * A_s1 + delta_v * delta_a * A_v1 + delta_v * I_v1 + delta_i * I_i1 + delta_a * delta_i * A_i1)/N1 + beta12 * (I_s2 + delta_a * A_s2 + delta_v * delta_a * A_v2 + delta_v * I_v2 + delta_i * I_i2 + delta_a * delta_i * A_i2)/N2 + beta13 * (I_s3 + delta_a * A_s3 + delta_v * delta_a * A_v3 + delta_v * I_v3 + delta_i * I_i3 + delta_a * delta_i * A_i3)/N3 + beta14 * (I_s4 + delta_a * A_s4 + delta_v * delta_a * A_v1 + delta_v * I_v4 + delta_i * I_i4 + delta_a * delta_i * A_i4)/N4
epsilon_current1 = epsilon1(t, V1, E_v1, I_v1, A_v1, R_v1, N1)
dS1dt = - Lambda1 * S1 - epsilon_current1 * S1
This worked with my previous code which was the same apart from the parameter only had one condition. Now i'm getting this error code...
--> 217 dS1dt = - Lambda1 * S1 - epsilon_current1 * S1
218 dS2dt = - Lambda2 * S2 - epsilon_current2 * S2
219 dS3dt = - Lambda3 * S3 - epsilon_current3 * S3
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'
The set up for epsilon2 and epsilon3 is the same as epsilon1 just with different values.
Just at the very top of your function you could implement a check, e.g.:
Lambda1 = 1.0; S1 = 2.0; epsilon_current = None
if any(x is None for x in [Lambda1, S1, epsilon_current]):
print("There's something fishy about these variables, really.")
# some cool error handling here
1st i need to get two equation of two longest line length
i put lenghths with eq in list like these [( length 1 , eq 1 ) ,.....]
sort list with reverse
get two equation of two longest line
when run the below code
from sympy import *
import math
class shape():
def __init__(self,T):
self.T=T
self.Ax = self.T[0][0]
self.Ay = self.T[0][1]
self.Bx = self.T[1][0]
self.By = self.T[1][1]
self.Cx = self.T[2][0]
self.Cy = self.T[2][1]
#Triangle:
self.C_dashx = 0.5 * (self.Ax + self.Bx)
self.C_dashy = 0.5 * (self.Ay + self.By)
self.B_dashx = 0.5 * (self.Ax + self.Cx)
self.B_dashy = 0.5 * (self.Ay + self.Cy)
self.A_dashx = 0.5 * (self.Bx + self.Cx)
self.A_dashy = 0.5 * (self.By + self.Cy)
if (self.Ax - self.A_dashx) == 0:
self.m_AA =0
else:
self.m_AA = (self.Ay - self.A_dashy) / (self.Ax - self.A_dashx)
if (self.Bx - self.B_dashx) == 0:
self.m_BB =0
else:
self.m_BB = (self.By - self.B_dashy) / (self.Bx - self.B_dashx)
if (self.Bx - self.B_dashx) == 0:
self.m_CC =0
else:
self.m_CC = (self.Cy - self.C_dashy) / (self.Bx - self.B_dashx)
def triangle_intersection(self):
self.x , self.y = symbols('x y')
self.eq1=Eq(self.m_AA*(self.x-self.Ax)+self.Ay-self.y,0)
self.eq2=Eq(self.m_BB*(self.x-self.Bx)+self.By-self.y,0)
self.solve_equation=solve([self.eq1,self.eq2],[self.x,self.y])
self.Zx=(self.solve_equation[self.x]).factor()
self.Zy=(self.solve_equation[self.y]).factor()
print(self.Zx,self.Zy)
def square_intersection(self):
self.Dx = self.T[3][0]
self.Dy = self.T[3][0]
# Line Solpe:
if (self.Bx - self.Ax) == 0:
self.m_AB = 0
else:
self.m_AB = (self.By - self.Ay) / (self.Bx - self.Ax)
if (self.Dx - self.Ax) == 0:
self.m_AD = 0
else:
self.m_AD = (self.Dy - self.Ay) / (self.Dx - self.Ax)
if (self.Cx - self.Bx) == 0:
self.m_BC = 0
else:
self.m_BC = (self.Cy - self.By) / (self.Cx - self.Bx)
if (self.Dx - self.Bx) == 0:
self.m_BD = 0
else:
self.m_BD = (self.Dy - self.By) / (self.Dx - self.Bx)
if (self.Dx - self.Cx) == 0:
self.m_CD = 0
else:
self.m_CD = (self.Dy - self.Cy) / (self.Dx - self.Cx)
if (self.Cx - self.Ax) == 0:
self.m_AC = 0
else:
self.m_AC = (self.Cy - self.Ay) / (self.Cx - self.Ax)
# Equation:
#### WHAT IS PROBLEM HERE###########
self.z, self.t = symbols('z t',positive=True)
self.eq_AB = Eq(self.m_AB * (self.z - self.Ax) + self.Ay - self.t,0)
self.eq_AC = Eq(self.m_AC * (self.z - self.Ax) + self.Ay - self.t,0)
self.eq_AD = Eq(self.m_AD * (self.z - self.Ax) + self.Ay - self.t,0)
self.eq_BC = Eq(self.m_BC * (self.z - self.Bx) + self.By - self.t,0)
self.eq_BD = Eq(self.m_BD * (self.z - self.Bx) + self.By - self.t,0)
self.eq_CD = Eq(self.m_CD * (self.z - self.Cx) + self.Cy - self.t,0)
self.length_AB = math.sqrt((self.Bx - self.Ax)**2 + (self.By - self.Ay)**2)
self.length_AC = math.sqrt((self.Cx - self.Ax)**2 + (self.Cy - self.Ay)**2)
self.length_AD = math.sqrt((self.Dx - self.Ax)**2 + (self.Dy - self.Ay)**2)
self.length_BC = math.sqrt((self.Cx - self.Bx)**2 + (self.Cy - self.By)**2)
self.length_BD = math.sqrt((self.Dx - self.Bx)**2 + (self.Dy - self.By)**2)
self.length_CD = math.sqrt((self.Dx - self.Cx)**2 + (self.Dy - self.Cy)**2)
#### WHAT IS PROBLEM HERE###########
self.lenghts = [(self.length_AB, self.eq_AB),(self.length_AC, self.eq_AC),(self.length_AD, self.eq_AD),(self.length_BC, self.eq_BC)
, (self.length_BD, self.eq_BD), (self.length_CD, self.eq_CD)]
self.newlenghts = sorted(self.lenghts,reverse=True)
self.max1=self.newlenghts[0][1]
self.max2=self.newlenghts[1][1]
self.solve_equation_sq = solve([self.max1, self.max2], [self.z, self.t])
print(self.solve_equation_sq)
self.Rx = (self.solve_equation_sq[self.z]).factor()
self.Ry = (self.solve_equation_sq[self.t]).factor()
print(self.Rx, self.Ry)
test=[(0,0),(4,0),(4,4),(0,4)]
a1=shape(test)
a1.triangle_intersection()
a1.square_intersection()
i got the below error
2.66666666666667 1.33333333333333
{z: t}
Traceback (most recent call last):
File "C:/Users/xxxxx/.PyCharmCE2019.3/config/scratches/programme logic function.py", line 127, in
a1.square_intersection()
File "C:/Users/xxxxx/.PyCharmCE2019.3/config/scratches/programme logic function.py", line 119, in square_intersection
self.Ry = (self.solve_equation_sq[self.t]).factor()
KeyError: t
If you print out the equations you are trying to solve you will see that they are the same so the only solution returned is {z:t} not {z:smthng, t:smthngelse}. So when you request the value of t it tells you that there is no t in the solution dictionary. Now you have to go back and see that you properly computed that equations that were to be solved.
Note, too, that SymPy has the Polygon/Triangle objects and might already have a method to answer the question that you are asking.
I got the error
File "C:/Users/", line 70, in <module>
cal_PIN()
File "C:/Users/", line 67, in cal_PIN
cal_likelihood(selling_5_tick, buying_5_tick)
File "C:/Users/", line 48, in cal_likelihood
raise valueErr(result.message)
valueErr: Desired error not necessarily achieved due to precision loss.
I want to estimate the parameter in the pin model. The Log converted likelihood function is the same as the attached photo. The parameters to be estimated are (α, δ, μ, εB, εS). I coded the 3-steps-for-statement to set the initial value. I try to used scipy.optimize.minimize to estimate the parameter by applying Maximum Likelihood Estimation.
import time
import scipy
from scipy.optimize import minimize
def f(params, *args):
# args={k1, k2, k3, kmi, buying_array[i], selling_array[i]}
k1 = args[0]
k2 = args[1]
k3 = args[2]
kmi = args[3]
buying_array = args[4]
selling_array = args[5]
ini_a, ini_h, ini_eS, ini_eB = params
return (-1) * (ini_a * ini_h * scipy.exp(k1 - kmi) + ini_a * (1 - ini_h) * scipy.exp(k2 - kmi) + (
1 - ini_a) * scipy.exp(k3 - kmi) +
(buying_array * scipy.log(ini_eB + ini_h) + selling_array * scipy.log(ini_eS + ini_h) - (
ini_eB + ini_eS) + kmi))
def cal_likelihood(selling_array, buying_array):
for ini_a in [0.1, 0.3, 0.5, 0.7, 0.9]:
for ini_h in [0.1, 0.3, 0.5, 0.7, 0.9]:
for z in [0.1, 0.3, 0.5, 0.7, 0.9]:
time.sleep(1)
i = 0
for i in range(0, len(buying_array)):
ini_eB = z * selling_array[i]
cal_u = (buying_array[i] - ini_eB) / (ini_a * (1 - ini_h))
ini_eS = selling_array[i] - (ini_a * ini_h * cal_u)
k1 = ((-1.0) * (cal_u) - buying_array[i] * scipy.log(1 + (cal_u / ini_eB)))
k2 = ((-1.0) * (cal_u) - selling_array[i] * scipy.log(1 + (cal_u / ini_eS)))
k3 = (-1.0) * buying_array[i] * scipy.log(1 +
(cal_u / ini_eB)) - selling_array[i] * scipy.log(
1 + (cal_u / ini_eS))
kmi = max(k1, k2, k3)
initial_guess = [ini_a, ini_h, ini_eB, ini_eS]
result = minimize(f, initial_guess, args=(k1, k2,
k3, kmi, buying_array[i], selling_array[i]))
if result.success:
fitted_params = result.x
print(fitted_params[0])
else:
raise ValueError(result.message)
def cal_PIN():
buying_5_tick = []
selling_5_tick = []
buying_5_tick.append(4035)
buying_5_tick.append(3522)
buying_5_tick.append(4073)
buying_5_tick.append(3154)
buying_5_tick.append(9556)
selling_5_tick.append(1840)
selling_5_tick.append(2827)
selling_5_tick.append(4095)
selling_5_tick.append(2602)
selling_5_tick.append(2230)
cal_likelihood(selling_5_tick, buying_5_tick)
I expected values where 0 < α < 1 and 0 < δ < 1, but something is wrong.
Well, as you raise the error yourself it is obvious, that the minimization fails because of the error Warning: Desired error not necessarily achieved due to precision loss.
Taken from a scipy issue:
This warning occurs when line search could not find a step size
meeting both Wolfe conditions and the Polak-Ribiere descent condition
within a certain number of iterations.
The results of your minimization don't seem to have any bound, as your objective function is just *-1 some values. This results in rather big derivatives and could lead to some ill-conditioned Hessian. Such ill-conditioned matrix then leads to the linesearch-fail.
One option would be to change the objective-return to
return 1 / (ini_a * ini_h * scipy.exp(k1 - kmi) + ini_a * (1 - ini_h) * scipy.exp(k2 - kmi) + (
1 - ini_a) * scipy.exp(k3 - kmi) +
(buying_array * scipy.log(ini_eB + ini_h) + selling_array * scipy.log(ini_eS + ini_h) - (
ini_eB + ini_eS) + kmi))
This leads to the results beign in the required range of 0 < value < 1.
If this is not an optimal solution for you, try changing solvers. Find some options in the documentation.
Also some tips and tricks for youre programming. You can use itertools.product to avoid such nested loops. Instead of appending each value, just declare a list.
Here are the suggestions and the working code.
import time
import scipy
from scipy.optimize import minimize
import itertools
def f(params, *args):
# args={k1, k2, k3, kmi, buying_array[i], selling_array[i]}
k1 = args[0]
k2 = args[1]
k3 = args[2]
kmi = args[3]
buying_array = args[4]
selling_array = args[5]
ini_a, ini_h, ini_eS, ini_eB = params
return 1 / (ini_a * ini_h * scipy.exp(k1 - kmi) + ini_a * (1 - ini_h) * scipy.exp(k2 - kmi) + (
1 - ini_a) * scipy.exp(k3 - kmi) +
(buying_array * scipy.log(ini_eB + ini_h) + selling_array * scipy.log(ini_eS + ini_h) - (
ini_eB + ini_eS) + kmi))
def cal_likelihood(selling_array, buying_array):
list_iteration = [0.1, 0.3, 0.5, 0.7, 0.9]
for (ini_a, ini_h, z) in itertools.product(*[list_iteration,list_iteration,list_iteration]):
time.sleep(1)
for i in range(0, len(buying_array)):
ini_eB = z * selling_array[i]
cal_u = (buying_array[i] - ini_eB) / (ini_a * (1 - ini_h))
ini_eS = selling_array[i] - (ini_a * ini_h * cal_u)
k1 = ((-1.0) * (cal_u) - buying_array[i] * scipy.log(1 + (cal_u / ini_eB)))
k2 = ((-1.0) * (cal_u) - selling_array[i] * scipy.log(1 + (cal_u / ini_eS)))
k3 = (-1.0) * buying_array[i] * scipy.log(1 +
(cal_u / ini_eB)) - selling_array[i] * scipy.log(
1 + (cal_u / ini_eS))
kmi = max(k1, k2, k3)
initial_guess = [ini_a, ini_h, ini_eB, ini_eS]
result = minimize(f, initial_guess, args=(k1, k2,
k3, kmi, buying_array[i], selling_array[i]))
if result.success:
fitted_params = result.x
print(fitted_params[0])
else:
raise ValueError(result.message)
def cal_PIN():
buying_5_tick = [4035, 3522, 4073, 3154, 9556]
selling_5_tick = [1840, 2827, 4095, 2602, 2230]
cal_likelihood(selling_5_tick, buying_5_tick)
cal_PIN()