/
costed.py
73 lines (64 loc) · 2.89 KB
/
costed.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
"Implement CostedConstraintSet"
import numpy as np
from .set import ConstraintSet, add_meq_bounds
from ..small_scripts import maybe_flatten
class CostedConstraintSet(ConstraintSet):
"""A ConstraintSet with a cost
Arguments
---------
cost : gpkit.Posynomial
constraints : Iterable
substitutions : dict (None)
"""
lineage = None
def __init__(self, cost, constraints, substitutions=None):
self.cost = maybe_flatten(cost)
if isinstance(self.cost, np.ndarray): # if it's still a vector
raise ValueError("Cost must be scalar, not the vector %s." % cost)
subs = dict(self.cost.varkeyvalues())
if substitutions:
subs.update(substitutions)
ConstraintSet.__init__(self, constraints, subs)
def __bare_init__(self, cost, constraints, substitutions):
self.cost = cost
self.substitutions = substitutions or {}
if not isinstance(constraints, ConstraintSet):
if isinstance(constraints, dict):
self.idxlookup = {k: i for i, k in enumerate(constraints)}
constraints = constraints.values()
constraints = ConstraintSet(constraints)
list.__init__(self, constraints)
else:
list.__init__(self, [constraints])
self.varkeys = constraints.varkeys
self.varkeys.update(cost.varkeys)
self.bounded = constraints.bounded
for exp in cost.hmap:
for vk, x in exp.items():
self.bounded.add((vk, "upper" if x > 0 else "lower"))
self.meq_bounded = constraints.meq_bounded
add_meq_bounds(self.bounded, self.meq_bounded)
def constrained_varkeys(self):
"Return all varkeys in the cost and non-ConstraintSet constraints"
constrained_varkeys = ConstraintSet.constrained_varkeys(self)
constrained_varkeys.update(self.cost.varkeys)
return constrained_varkeys
def reset_varkeys(self):
"Resets varkeys to what is in the cost and constraints"
ConstraintSet.reset_varkeys(self)
self.varkeys.update(self.cost.varkeys)
def _rootlines(self, excluded=()):
"String showing cost, to be used when this is the top constraint"
description = ["", "Cost", "----",
" %s" % self.cost.str_without(excluded),
"", "Constraints", "-----------"]
if self.lineage:
name, num = self.lineage[-1] # pylint: disable=unsubscriptable-object
fullname = "%s" % (name if not num else name + str(num))
description = [fullname, "="*len(fullname)] + description
return description
def _rootlatex(self, excluded=()):
"Latex showing cost, to be used when this is the top constraint"
return "\n".join(["\\text{minimize}",
" & %s \\\\" % self.cost.latex(excluded),
"\\text{subject to}"])