Skip to content

Commit

Permalink
Merge branch 'master' of github.com:cvxgrp/cvxpy
Browse files Browse the repository at this point in the history
* 'master' of github.com:cvxgrp/cvxpy:
  ENH: Clearer error when rejecting a solver. (cvxpy#329)
  examples: ADMM Lasso: fix missing variables (cvxpy#325)
  • Loading branch information
Steven Diamond committed Feb 21, 2017
2 parents cf35328 + ded6dfd commit 825b68c
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 18 deletions.
40 changes: 30 additions & 10 deletions cvxpy/problems/solvers/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,36 @@ def validate_solver(self, constraints):
raise SolverError("The solver %s is not installed." % self.name())
# Check the solver can solve the problem.
constr_map = SymData.filter_constraints(constraints)
if ((constr_map[s.BOOL] or constr_map[s.INT]) and
not self.MIP_CAPABLE) or \
(constr_map[s.SDP] and not self.SDP_CAPABLE) or \
(constr_map[s.EXP] and not self.EXP_CAPABLE) or \
(constr_map[s.SOC] and not self.SOCP_CAPABLE) or \
(len(constraints) == 0 and self.name() in [s.SCS,
s.GLPK]):
raise SolverError(
"The solver %s cannot solve the problem." % self.name()
)

if (constr_map[s.BOOL] or constr_map[s.INT]) and not self.MIP_CAPABLE:
self._reject_problem("it cannot solve mixed-integer problems")
elif constr_map[s.SDP] and not self.SDP_CAPABLE:
self._reject_problem("it cannot solve semidefinite problems")
elif constr_map[s.EXP] and not self.EXP_CAPABLE:
self._reject_problem("it cannot solve exponential cone problems")
elif constr_map[s.SOC] and not self.SOCP_CAPABLE:
self._reject_problem("it cannot solve second-order cone problems")
elif len(constraints) == 0 and self.name() in (s.SCS, s.GLPK):
self._reject_problem("it cannot solve unconstrained problems")

def _reject_problem(self, reason):
"""Raise an error indicating that the solver cannot solve a problem.
Parameters
----------
reason : str
A short description of the reason the problem cannot be solved by
this solver.
Raises
------
cvxpy.SolverError
An error explaining why the problem could not be solved.
"""
message = "The solver {} cannot solve the problem because {}.".format(
self.name(), reason
)
raise SolverError(message)

def validate_cache(self, objective, constraints, cached_data):
"""Clears the cache if the objective or constraints changed.
Expand Down
32 changes: 24 additions & 8 deletions cvxpy/tests/test_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,17 @@ def test_solver_stats(self):
self.assertGreater(stats.setup_time, 0)
self.assertGreater(stats.num_iters, 0)


def test_get_problem_data(self):
"""Test get_problem_data method.
"""
with self.assertRaises(Exception) as cm:
Problem(Maximize(Bool())).get_problem_data(s.ECOS)
self.assertEqual(str(cm.exception), "The solver ECOS cannot solve the problem.")

expected = (
"The solver ECOS cannot solve the problem because"
" it cannot solve mixed-integer problems."
)
self.assertEqual(str(cm.exception), expected)

data = Problem(Maximize(exp(self.a) + 2)).get_problem_data(s.SCS)
dims = data["dims"]
Expand Down Expand Up @@ -1270,18 +1274,30 @@ def test_invalid_solvers(self):
"""
with self.assertRaises(Exception) as cm:
Problem(Minimize(Bool())).solve(solver=s.ECOS)
self.assertEqual(str(cm.exception),
"The solver ECOS cannot solve the problem.")

expected = (
"The solver ECOS cannot solve the problem "
"because it cannot solve mixed-integer problems."
)
self.assertEqual(str(cm.exception), expected)

with self.assertRaises(Exception) as cm:
Problem(Minimize(lambda_max(self.a))).solve(solver=s.ECOS)
self.assertEqual(str(cm.exception),
"The solver ECOS cannot solve the problem.")

expected = (
"The solver ECOS cannot solve the problem "
"because it cannot solve semidefinite problems."
)
self.assertEqual(str(cm.exception), expected)

with self.assertRaises(Exception) as cm:
Problem(Minimize(self.a)).solve(solver=s.SCS)
self.assertEqual(str(cm.exception),
"The solver SCS cannot solve the problem.")

expected = (
"The solver SCS cannot solve the problem "
"because it cannot solve unconstrained problems."
)
self.assertEqual(str(cm.exception), expected)

def test_reshape(self):
"""Tests problems with reshape.
Expand Down
2 changes: 2 additions & 0 deletions examples/admm_lasso.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# Problem data.
m = 100
n = 75
gamma = 1.0
NUM_PROCS = 2
np.random.seed(1)
A = np.random.randn(m, n)
b = np.random.randn(m, 1)
Expand Down

0 comments on commit 825b68c

Please sign in to comment.