When using CVXPY, I frequently get "SolverError". Their doc just says this is caused by numerical issues, but no further information is given about how to avoid them.
The following code snippet is an example, the problem is trivial, but the 'CVXOPT' solver just throws "SolverError". It is true that if we change the solver to another one, like 'ECOS', the problem will be solved as expected. But the point is, 'CVXOPT' should in principle solve this trivial problem and it really baffles me why it doesn't work.
import numpy as np
import cvxpy as cv
np.random.seed(0)
temp = np.random.rand(5)
T = 2
x = cv.Variable(T)
u = cv.Variable(2, T)
pbs = []
for t in range(T):
cost = cv.sum_squares(x[t]-temp[t])
constr = [x[t] == u[0,t]+u[1,t],]
pbs.append(cv.Problem(cv.Minimize(cost), constr))
prob = sum(pbs)
prob.solve(solver='CVXOPT')
Use prob.solve(solver='CVXOPT', kktsolver=cv.ROBUST_KKTSOLVER) to make the optimisation process more robust.
Related
I am facing a major issues in python using sympy. I didn't find any solutions to my problem or at least, I couldn't apply the solutions I found on my problem.
import sympy as sp
import math as ma
import numpy as np
E1=72500
A1=15
U01,s,C1,U02 = sp.symbols("U01,s,C1,U02")
u1 = sp.symbols("u1", cls=sp.Function)
eqs=sp.Eq(E1*A1*u1(s).diff(s)+180+U02,0)
sol=sp.dsolve(eqs,dict=True)
expr=sol.args[1]
u1=sp.lambdify(s,expr.subs(C1,U01))
print(u1(s))
#gives me : U01 - 9.19540229885057e-7*U02*s - 0.00016551724137931*s
expression1=u1(10)-54
expression2=u1(7)-99
eq1=sp.Eq(expression1,0)
eq2=sp.Eq(expression2,0)
solution = sp.solve([eq1,eq2],[U01,U02])
U01=float(solution[U01])
U02=float(solution[U02])
print(u1(55))
# gives me : U01 - 5.05747126436782e-5*U02 - 0.00910344827586207
I want to evaluate u1(55), but I still get the expression.
Thank you very much in advance.
I expect to get :
-621.0000000000018
Don't override U01 and U02 by numerical values, use intermediate variables. You have to evaluate your lambda function with solution previously found:
...
solution = sp.solve([eq1, eq2], [U01, U02])
U01_val = float(solution[U01])
U02_val = float(solution[U02])
result = u1(55).evalf(subs={U01: U01_val, U02: U02_val})
print(result)
# Output
-621.000000000001
Or simply:
...
solution = sp.solve([eq1, eq2], [U01, U02])
result = u1(55).evalf(subs=solution)
print(result)
# Output
-621.000000000001
I am trying to solve a MIP, I use pyomo, and Cplex(Interactive Optimizer 20.1.0.0) is solver.
The problem is that I want to fix some binary integer variables then solve the problem, and I used:
model.y[1,4].fix(1)
model.y[2,3].fix(0)
, but I have noticed that after solving the problem those fixed variables have changed to another values.
How can I say cplex to not change that fixed variables?
let me use the bus example for fixed start with pyomo
import pyomo.environ as pyo
from pyomo.opt import SolverFactory
opt = pyo.SolverFactory("cplex")
model = pyo.ConcreteModel()
model.nbBus = pyo.Var([40,30], domain=pyo.PositiveIntegers)
#fixed start
model.nbBus[40].fix(3)
# end of fixed start
model.OBJ = pyo.Objective(expr = 500*model.nbBus[40] + 400*model.nbBus[30])
model.Constraint1 = pyo.Constraint(expr = 40*model.nbBus[40] + 30*model.nbBus[30] >= 300)
results = opt.solve(model)
print("nbBus40=",int(model.nbBus[40].value))
print("nbBus30=",int(model.nbBus[30].value))
gives
nbBus40= 3
nbBus30= 6
whereas if you remove the fixed start you get
nbBus40= 6
nbBus30= 2
Since fixing variable didn't work for me, I tackle my problem with adding a new constraint to the model, and it works.
def yvar_fix(model, i, j ):
if (i,j) in y_set_init:
constraint = (model.y[i,j] == 1)
else:
constraint = (model.y[i,j] == 0)
return constraint
model.yvar_fix = pe.Constraint(model.edges, rule=yvar_fix)
I am trying to separately compute the elements of a Taylor expansion and did not obtain the results I was supposed to. The function to approximate is x**321, and the first three elements of that Taylor expansion around x=1 should be:
1 + 321(x-1) + 51360(x-1)**2
For some reason, the code associated with the second term is not working.
See my code below.
import sympy as sy
import numpy as np
import math
import matplotlib.pyplot as plt
x = sy.Symbol('x')
f = x**321
x0 = 1
func0 = f.diff(x,0).subs(x,x0)*((x-x0)**0/factorial(0))
print(func0)
func1 = f.diff(x,1).subs(x,x0)*((x-x0)**1/factorial(1))
print(func1)
func2 = f.diff(x,2).subs(x,x0)*((x-x0)**2/factorial(2))
print(func2)
The prints I obtain running this code are
1
321x - 321
51360*(x - 1)**2
I also used .evalf and .lambdify but the results were the same. I can't understand where the error is coming from.
f = x**321
x = sy.Symbol('x')
def fprime(x):
return sy.diff(f,x)
DerivativeOfF = sy.lambdify((x),fprime(x),"numpy")
print(DerivativeOfF(1)*((x-x0)**1/factorial(1)))
321*x - 321
I'm obviously just starting with the language, so thank you for your help.
I found a beginners guide how to Taylor expand in python. Check it out perhaps all your questions are answered there:
http://firsttimeprogrammer.blogspot.com/2015/03/taylor-series-with-python-and-sympy.html
I tested your code and it works fine. like Bazingaa pointed out in the comments it is just an issue how python saves functions internally. One could argument that for a computer it takes less RAM to save 321*x - 321 instead of 321*(x - 1)**1.
In your first output line it also gives you 1 instead of (x - 1)**0
I am trying to implement an algorithm in the following paper (method 5) http://dx.doi.org/10.1016%2FS0076-6879(05)09012-9 in python2.7 to improve my programming skill. Implementations can be found at these locations: Apparently I cannot post so many links. If my reputation goes up, I will post the links here.
Essentially, the algorithm is used for biological research, and finds the mutation rate of cells under some condition. Here is my attempt, which has errors (NOTE: I updated this code to remove an error however I am still not getting the right answer):
import numpy as np
import sympy as sp
from scipy.optimize import minimize
def leeCoulson(nparray):
median=np.median(nparray)
x=sp.Symbol('x')
M_est=sp.solve(sp.Eq(-x*sp.log(x) - 1.24*x + median,0),x)
return M_est
def ctArray(nparray,max):
list=[0] * int(max+1)
for i in range(int(max)+1):
list[i]=nparray.count(i)
return list
values='filename1.csv'
data=np.genfromtxt(values,delimiter=',')
mVal=int(max(data))
ctArray_=ctArray(np.ndarray.tolist(data),mVal)
ef mssCalc(estM,max=mVal,count=ctArray_):
def rec(pi,r):
pr=(estM/r)+sum([(pi[i]/(r-i+1)) for i in range(0,r-1)])
return pr
prod=1
pi=[0]*max
pi[0]=np.exp(-1*estM)
for r in range(1,max):
pi[r]=rec(pi,r)
prod=prod*(pi[r]**count[r])
return -1*prod
finalM=minimize (mssCalc,leeCoulson(data),method='nelder-mead',options={'xtol':1e-3,'disp':True})
print finalM
This code gives the following errors:
mss-mle_calc.py:37: RuntimeWarning: overflow encountered in multiply
prod=prod*(pi[r]**count[r])
/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/scipy/optimize/optimize.py:462: RuntimeWarning: invalid value encountered in subtract
numpy.max(numpy.abs(fsim[0] - fsim[1:])) <= ftol):
Warning: Maximum number of function evaluations has been exceeded.
Please help me make this code better if you have some time.
Thanks for looking, there were a couple stupid mistakes in my code. Here is the working code (as far as I can tell):
import numpy as np
import sympy as sp
from scipy.optimize import minimize
def leeCoulson(nparray):
median=np.median(nparray)
x=sp.Symbol('x')
M_est=sp.solve(sp.Eq(-x*sp.log(x) - 1.24*x + median,0),x)
return float(M_est[0])
def ctArray(nparray,max):
list=[0] * int(max+1)
for i in range(int(max)+1):
list[i]=nparray.count(i)
return list
values='filename1.csv'
data=np.genfromtxt(values,delimiter=',')
mVal=int(max(data))
ctArray_=ctArray(np.ndarray.tolist(data),mVal)
def mssCalc(estM,max=mVal,count=ctArray_):
def rec(pi,r):
pr=(estM/r)*sum([(pi[i]/(r-i+1)) for i in range(0,r)])
return pr
prod=1
pi=[0]*(max+1)
pi[0]=np.exp(-1.0*estM)
for r in range(1,max+1):
pi[r]=rec(pi,r)
prod=prod*(pi[r]**count[r])
return -1*prod
finalM=minimize (mssCalc,leeCoulson(data),method='nelder-mead',options={'xtol':1e-3,'disp':True})
print finalM
I am new with scipy and python. I have searched quite extensively to find a tool similar to Excel Solver in Python and scipy seems to be very powerful. My question is kinda simple. I was trying to find the discount rate for a series of cash flows so that the sum of the present value of CFs equates to a specific value.
I got this error message if I run the codes. 1500 is my target value so I try to minimize the difference between my target value and f(DR).
RuntimeWarning: overflow encountered in multiply
DRfactor[i] = DRfactor[i-1]*(1+DRs[i])
Any and all help is much appreciated
import numpy as np
import scipy as sp
import scipy.optimize
def f(DR):
CFs = [100]*50
DRs = [np.nan]*50
DRfactor = [np.nan]*50
for i in range(0,50):
if 0<=i<=4:
DRs[i] = DR
else:
DRs[i] = (DRs[i-1]-0.1)*0.9+0.1
if i == 0:
DRfactor[i] = 1+DRs[i]
else:
DRfactor[i] = DRfactor[i-1]*(1+DRs[i])
CFPV = np.divide(CFs, DRfactor)
CFsum = np.sum(CFPV)
return (CFsum - 1500)**2
print (f(0.05))
sol = sp.optimize.minimize(f, 0.05)
sol.x
I figured it out. scipy.optimize.newton can zero out f(DR) and give 0.041611073570941355 which is the same answer given by excel solver.