/
globals.py
137 lines (111 loc) · 4.64 KB
/
globals.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
"global mutable variables"
from __future__ import unicode_literals, print_function
import os
import sys
from collections import defaultdict
from six import with_metaclass
from . import build
def load_settings(path=None, firstattempt=True):
"Load the settings file at SETTINGS_PATH; return settings dict"
if path is None:
path = os.sep.join([os.path.dirname(__file__), "env", "settings"])
try:
with open(path) as settingsfile:
lines = [line[:-1].split(" : ") for line in settingsfile
if len(line.split(" : ")) == 2]
settings_ = {name: value.split(", ") for name, value in lines}
for name, value in settings_.items():
# hack to flatten 1-element lists,
# unless they're the solver list
if len(value) == 1 and name != "installed_solvers":
settings_[name] = value[0]
if sys.version_info >= (3, 0) and name == "installed_solvers":
if "mosek" in value:
value.remove("mosek")
except IOError:
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()
settings_ = load_settings(path, firstattempt=False)
if settings_["installed_solvers"] != [""]:
settings_["just built!"] = True
else:
print("""
=============
Build failed! :(
=============
You may need to install a solver and then `import gpkit` again;
see https://gpkit.readthedocs.io/en/latest/installation.html
for troubleshooting details.
But before you go, please post the output above
(starting from "Found no installed solvers, beginning a build.")
to gpkit@mit.edu or https://github.com/convexengineering/gpkit/issues/new
so we can prevent others from having to see this message.
Thanks! :)
""")
settings_["default_solver"] = settings_["installed_solvers"][0]
return settings_
settings = load_settings()
class SignomialsEnabledMeta(type):
"Metaclass to implement falsiness for SignomialsEnabled"
def __nonzero__(cls):
return 1 if cls._true else 0
def __bool__(cls):
return cls._true
class SignomialsEnabled(with_metaclass(SignomialsEnabledMeta)): # pylint: disable=no-init
"""Class to put up and tear down signomial support in an instance of GPkit.
Example
-------
>>> import gpkit
>>> x = gpkit.Variable("x")
>>> y = gpkit.Variable("y", 0.1)
>>> with SignomialsEnabled():
>>> constraints = [x >= 1-y]
>>> gpkit.Model(x, constraints).localsolve()
"""
_true = False # the current signomial permissions
def __enter__(self):
SignomialsEnabled._true = True
def __exit__(self, type_, val, traceback):
SignomialsEnabled._true = False
class Vectorize(object):
"""Creates an environment in which all variables are
exended in an additional dimension.
"""
vectorization = () # the current vectorization shape
def __init__(self, dimension_length):
self.dimension_length = dimension_length
def __enter__(self):
"Enters a vectorized environment."
Vectorize.vectorization = (self.dimension_length,) + self.vectorization
def __exit__(self, type_, val, traceback):
"Leaves a vectorized environment."
Vectorize.vectorization = self.vectorization[1:]
class NamedVariables(object):
"""Creates an environment in which all variables have
a model name and num appended to their varkeys.
"""
lineage = () # the current model nesting
modelnums = defaultdict(int) # the number of models of each lineage
namedvars = defaultdict(list) # variables created in the current nesting
@classmethod
def reset_modelnumbers(cls):
"Clear all model number counters"
for key in list(cls.modelnums):
del cls.modelnums[key]
def __init__(self, name):
self.name = name
def __enter__(self):
"Enters a named environment."
num = self.modelnums[(self.lineage, self.name)]
self.modelnums[(self.lineage, self.name)] += 1
NamedVariables.lineage += ((self.name, num),) # NOTE: Class reference
return self.lineage, self.namedvars[self.lineage]
def __exit__(self, type_, val, traceback):
"Leaves a named environment."
del self.namedvars[self.lineage]
NamedVariables.lineage = self.lineage[:-1] # NOTE: Class reference