Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes #1443

Merged
merged 7 commits into from
Oct 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion gpkit/globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ def load_settings(path=None, firstattempt=True):
value.remove("mosek")
except IOError:
settings_ = {"installed_solvers": [""]}
if settings_["installed_solvers"] == [""]:
if (settings_["installed_solvers"] == [""]
or ("mosek" in settings_["installed_solvers"]
and "mosek_version" not in settings_)):
if firstattempt:
print("Found no installed solvers, beginning a build.")
build()
Expand Down
23 changes: 16 additions & 7 deletions gpkit/nomials/math.py
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ def mono_approximation(self, x0):
class ScalarSingleEquationConstraint(SingleEquationConstraint):
"A SingleEquationConstraint with scalar left and right sides."
nomials = []
sgp_parent = None

def __init__(self, left, oper, right):
lr = [left, right]
Expand All @@ -394,14 +395,18 @@ def __init__(self, left, oper, right):
def relaxed(self, relaxvar):
"Returns the relaxation of the constraint in a list."
if self.oper == ">=":
return [relaxvar*self.left >= self.right]
relaxed = [relaxvar*self.left >= self.right]
elif self.oper == "<=":
return [self.left <= relaxvar*self.right]
relaxed = [self.left <= relaxvar*self.right]
elif self.oper == "=":
return [self.left <= relaxvar*self.right,
relaxvar*self.left >= self.right]
raise ValueError(
"Constraint %s had unknown operator %s." % self.oper, self)
relaxed = [self.left <= relaxvar*self.right,
relaxvar*self.left >= self.right]
else:
raise ValueError(
"Constraint %s had unknown operator %s." % self.oper, self)
for constr in relaxed:
constr.sgp_parent = self
return relaxed


# pylint: disable=too-many-instance-attributes, invalid-unary-operand-type
Expand All @@ -412,7 +417,6 @@ class PosynomialInequality(ScalarSingleEquationConstraint):
"""

feastol = 1e-3
sgp_parent = None
relax_sensitivity = None
# NOTE: follows .check_result's max default, but 1e-3 seems a bit lax...

Expand Down Expand Up @@ -519,6 +523,8 @@ def sens_from_dual(self, la, nu, result): # pylint: disable=unused-argument
self.relax_sensitivity = la
if self.sgp_parent:
self.sgp_parent.relax_sensitivity = la
if getattr(self.sgp_parent, "sgp_parent", None):
self.sgp_parent.sgp_parent.relax_sensitivity = la
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are there two layers of sgp_parent here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh let me guess, because you can have relaxations and SP approximations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup.

nu, = nu
presub, = self.unsubbed
if hasattr(self, "pmap"):
Expand Down Expand Up @@ -600,6 +606,9 @@ def sens_from_dual(self, la, nu, result):
self.relax_sensitivity = la[0] - la[1]
if self.sgp_parent:
self.sgp_parent.relax_sensitivity = self.relax_sensitivity
if getattr(self.sgp_parent, "sgp_parent", None):
self.sgp_parent.sgp_parent.relax_sensitivity = \
self.relax_sensitivity
var_senss = {}
for var in self.varkeys:
for i, m in enumerate(self.unsubbed):
Expand Down
2 changes: 1 addition & 1 deletion gpkit/repr_conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def unitstr(units, into="%s", options=UNIT_FORMATTING, dimless=""):
if not isinstance(units, Quantity):
return dimless
if options == ":~" and "ohm" in str(units.units):
rawstr = "ohm" # otherwise it'll be a capital Omega
rawstr = str(units.units) # otherwise it'll be a capital Omega
else:
rawstr = ("{%s}" % options).format(units.units)
units = rawstr.replace(" ", "").replace("dimensionless", dimless)
Expand Down
11 changes: 8 additions & 3 deletions gpkit/solution_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,14 @@ def tight_table(self, _, ntightconstrs=5, tight_senss=1e-2, **kwargs):
if not self.model:
return []
title = "Tightest Constraints"
data = [((-float("%+6.2g" % c.relax_sensitivity), str(c)),
"%+6.2g" % c.relax_sensitivity, id(c), c)
for c in self.model.flat() if c.relax_sensitivity >= tight_senss]
try:
data = [((-float("%+6.2g" % c.relax_sensitivity), str(c)),
"%+6.2g" % c.relax_sensitivity, id(c), c)
for c in self.model.flat()
if c.relax_sensitivity >= tight_senss]
except AttributeError:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree that this is a better error message!

print("Constraint %s had no `relax_sensitivity` attribute." % c)
return []
if not data:
lines = ["No constraints had a sensitivity above %+5.1g."
% tight_senss]
Expand Down