David Stonestrom 6/4/2014
objective value: inf
status: unbounded
import cvxpy as cvx
import numpy
n = 6;
m = 1;
# generate some constraints
numpy.random.seed(0) # for repeatibility
A = numpy.random.randn(m,n)
b = 10 * numpy.random.random([m,1])
p = cvx.Parameter(1,n,nonneg=True)
p.value = numpy.random.random([1,n]) # returnes values in the interval [0.0, 1.0)
x = cvx.Variable(n,1) # (n,1) will give a colum vector
objective = cvx.Maximize(p * cvx.sqrt(x))
constraint = [A*x <= b]
problem = cvx.Problem(objective, constraint)
print "A: ", A
print "b: ", b
print "p: ", p.value
A: [[ 1.76405235 0.40015721 0.97873798 2.2408932 1.86755799 -0.97727788]] b: [[ 4.37587211]] p: [[ 0.891773 0.96366276 0.38344152 0.79172504 0.52889492 0.56804456]]
/Users/stevend2/anaconda/envs/cvxpy/lib/python2.7/site-packages/ecos-1.0.4-py2.7-macosx-10.5-x86_64.egg/_ecos.py:3: UserWarning: Module cvxpy was already imported from /Users/stevend2/anaconda/envs/cvxpy/lib/python2.7/site-packages/cvxpy-0.2.0-py2.7.egg/cvxpy/__init__.pyc, but /Users/stevend2/PythonProjects/cvxpy/examples/notebooks is being added to sys.path
try:
print problem.solve(solver = cvx.ECOS) # the default
print problem.status
except Exception as e:
print e
None solver_error
This is the classic solver error outcome. The objective is 'None' and the status is 'solver_error.' Note that it did not raise an exception.
When this happens, the next step is to just try the other available solvers to see what they do.
try:
print problem.solve(solver=cvx.CVXOPT)
print problem.status
except Exception as e:
print e
math domain error
Using CVXOPT throws an exception: 'math domain error.' This will probably be rolled into the solver_error case above at some point.
SCS is the only solver left to try.
try:
print problem.solve(solver=cvx.SCS)
print problem.status
except Exception as e:
print e
2082.01956591 optimal
Here the numerical imprecision of SCS lets it find an optimal value. Note the printed objective value: 2082. Compare it to the numpy computed objective for the optimal value of x below:
print "numpy calculated objective value:", p.value.dot(numpy.sqrt(x.value))
numpy calculated objective value: [[ 2322.27407977]]
The two values differ by over 10%. Next is a demonstration of a better feasible point.
print "SCS objective value: ", p.value.dot(numpy.sqrt(x.value))
print "SCS constraint violation: ", A.dot(x.value) - b
x_better = x.value + [[0],[0],[9900000],[0],[0],[10000000]]
print "\nHigher objective and lower constraint violation:"
print "objective: ", p.value.dot(numpy.sqrt(x_better))
print "constraint violation: ", A.dot(x_better) - b
SCS objective value: [[ 2322.27407977]] SCS constraint violation: [[ 0.00387292]] Higher objective and lower constraint violation: objective: [[ 4672.30778292]] constraint violation: [[-83272.75224437]]
Compare the above results to the following unbounded problem which ECOS solves corectly.
$$ \textbf{maximize } f\left(x\right) = \sum_{i=1}^{6}\sqrt{x_i}$$x = cvx.Variable(6)
problem = cvx.Problem(cvx.Maximize(cvx.sum(cvx.sqrt(x))))
try:
print "ECOS:\n", problem.solve(solver=cvx.ECOS)
print problem.status
print "\nSCS:\n", problem.solve(solver=cvx.SCS)
print problem.status
print "\nCVXOPT:\n", problem.solve(solver=cvx.CVXOPT)
print problem.status
except Exception as e:
print "Error Error Error"
print e
ECOS: inf unbounded SCS: 3257.630475 optimal CVXOPT: Error Error Error math domain error
The takeaway from all of this is to try all the solvers and make sure that you believe the answer they give. One of the important pieces of this is manually testing the constraint violations and objective value. Also consider what the value of the objective and variables are saying about the origional problem.
Finally, please keep in mind that this is an open source project and is provided "as is" with no guarintee of correctness.