gamspy 1.18.3__py3-none-any.whl → 1.19.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gamspy/__init__.py +86 -98
- gamspy/__main__.py +6 -6
- gamspy/_algebra/__init__.py +13 -13
- gamspy/_algebra/condition.py +290 -194
- gamspy/_algebra/domain.py +103 -93
- gamspy/_algebra/expression.py +820 -799
- gamspy/_algebra/number.py +79 -70
- gamspy/_algebra/operable.py +185 -185
- gamspy/_algebra/operation.py +948 -845
- gamspy/_backend/backend.py +313 -311
- gamspy/_backend/engine.py +960 -960
- gamspy/_backend/local.py +124 -124
- gamspy/_backend/neos.py +567 -567
- gamspy/_cli/__init__.py +1 -1
- gamspy/_cli/cli.py +64 -64
- gamspy/_cli/gdx.py +377 -377
- gamspy/_cli/install.py +375 -372
- gamspy/_cli/list.py +94 -94
- gamspy/_cli/mps2gms.py +128 -128
- gamspy/_cli/probe.py +52 -52
- gamspy/_cli/retrieve.py +79 -79
- gamspy/_cli/run.py +158 -158
- gamspy/_cli/show.py +246 -255
- gamspy/_cli/uninstall.py +165 -165
- gamspy/_cli/util.py +94 -94
- gamspy/_communication.py +215 -215
- gamspy/_config.py +132 -132
- gamspy/_container.py +1694 -1452
- gamspy/_convert.py +720 -720
- gamspy/_database.py +271 -271
- gamspy/_extrinsic.py +181 -181
- gamspy/_miro.py +356 -352
- gamspy/_model.py +1803 -1615
- gamspy/_model_instance.py +701 -701
- gamspy/_options.py +780 -700
- gamspy/_serialization.py +156 -144
- gamspy/_symbols/__init__.py +17 -17
- gamspy/_symbols/alias.py +305 -299
- gamspy/_symbols/equation.py +1407 -1298
- gamspy/_symbols/implicits/__init__.py +11 -11
- gamspy/_symbols/implicits/implicit_equation.py +186 -186
- gamspy/_symbols/implicits/implicit_parameter.py +272 -272
- gamspy/_symbols/implicits/implicit_set.py +124 -124
- gamspy/_symbols/implicits/implicit_symbol.py +315 -315
- gamspy/_symbols/implicits/implicit_variable.py +255 -255
- gamspy/_symbols/parameter.py +648 -609
- gamspy/_symbols/set.py +985 -923
- gamspy/_symbols/symbol.py +395 -386
- gamspy/_symbols/universe_alias.py +182 -182
- gamspy/_symbols/variable.py +1101 -1017
- gamspy/_types.py +7 -7
- gamspy/_validation.py +735 -735
- gamspy/_workspace.py +72 -72
- gamspy/exceptions.py +128 -128
- gamspy/formulations/__init__.py +46 -46
- gamspy/formulations/ml/__init__.py +11 -11
- gamspy/formulations/ml/decision_tree_struct.py +80 -80
- gamspy/formulations/ml/gradient_boosting.py +203 -203
- gamspy/formulations/ml/random_forest.py +187 -187
- gamspy/formulations/ml/regression_tree.py +533 -533
- gamspy/formulations/nn/__init__.py +19 -19
- gamspy/formulations/nn/avgpool2d.py +232 -232
- gamspy/formulations/nn/conv1d.py +533 -533
- gamspy/formulations/nn/conv2d.py +529 -529
- gamspy/formulations/nn/linear.py +341 -341
- gamspy/formulations/nn/maxpool2d.py +88 -88
- gamspy/formulations/nn/minpool2d.py +88 -88
- gamspy/formulations/nn/mpool2d.py +245 -245
- gamspy/formulations/nn/torch_sequential.py +278 -278
- gamspy/formulations/piecewise.py +682 -682
- gamspy/formulations/result.py +119 -119
- gamspy/formulations/shape.py +188 -188
- gamspy/formulations/utils.py +173 -173
- gamspy/math/__init__.py +215 -215
- gamspy/math/activation.py +783 -767
- gamspy/math/log_power.py +435 -435
- gamspy/math/matrix.py +534 -534
- gamspy/math/misc.py +1709 -1625
- gamspy/math/probability.py +170 -170
- gamspy/math/trigonometric.py +232 -232
- gamspy/utils.py +810 -791
- gamspy/version.py +5 -5
- {gamspy-1.18.3.dist-info → gamspy-1.19.0.dist-info}/METADATA +90 -121
- gamspy-1.19.0.dist-info/RECORD +90 -0
- {gamspy-1.18.3.dist-info → gamspy-1.19.0.dist-info}/WHEEL +1 -1
- {gamspy-1.18.3.dist-info → gamspy-1.19.0.dist-info}/licenses/LICENSE +22 -22
- gamspy-1.18.3.dist-info/RECORD +0 -90
- {gamspy-1.18.3.dist-info → gamspy-1.19.0.dist-info}/entry_points.txt +0 -0
- {gamspy-1.18.3.dist-info → gamspy-1.19.0.dist-info}/top_level.txt +0 -0
gamspy/_backend/backend.py
CHANGED
|
@@ -1,311 +1,313 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
from abc import ABC, abstractmethod
|
|
5
|
-
from typing import TYPE_CHECKING, Literal, no_type_check
|
|
6
|
-
|
|
7
|
-
import pandas as pd
|
|
8
|
-
|
|
9
|
-
import gamspy._symbols as syms
|
|
10
|
-
import gamspy.utils as utils
|
|
11
|
-
from gamspy.exceptions import GamspyException, ValidationError
|
|
12
|
-
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
import io
|
|
15
|
-
from pathlib import Path
|
|
16
|
-
|
|
17
|
-
from gamspy import Container, Model, Options
|
|
18
|
-
from gamspy._backend.engine import EngineClient, GAMSEngine
|
|
19
|
-
from gamspy._backend.local import Local
|
|
20
|
-
from gamspy._backend.neos import NeosClient, NEOSServer
|
|
21
|
-
from gamspy._symbols.symbol import Symbol
|
|
22
|
-
|
|
23
|
-
SOLVE_STATUS = [
|
|
24
|
-
"",
|
|
25
|
-
"Normal",
|
|
26
|
-
"Iteration",
|
|
27
|
-
"Resource",
|
|
28
|
-
"Solver",
|
|
29
|
-
"EvalError",
|
|
30
|
-
"Capability",
|
|
31
|
-
"License",
|
|
32
|
-
"User",
|
|
33
|
-
"SetupErr",
|
|
34
|
-
"SolverErr",
|
|
35
|
-
"InternalErr",
|
|
36
|
-
"Skipped",
|
|
37
|
-
"SystemErr",
|
|
38
|
-
]
|
|
39
|
-
HEADER = [
|
|
40
|
-
"Solver Status",
|
|
41
|
-
"Model Status",
|
|
42
|
-
"Objective",
|
|
43
|
-
"Num of Equations",
|
|
44
|
-
"Num of Variables",
|
|
45
|
-
"Model Type",
|
|
46
|
-
"Solver",
|
|
47
|
-
"Solver Time",
|
|
48
|
-
]
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@no_type_check
|
|
52
|
-
def backend_factory(
|
|
53
|
-
container: Container,
|
|
54
|
-
options: Options | None = None,
|
|
55
|
-
solver: str | None = None,
|
|
56
|
-
solver_options: dict | Path | None = None,
|
|
57
|
-
output: io.TextIOWrapper | None = None,
|
|
58
|
-
backend: Literal["local", "engine", "neos"] = "local",
|
|
59
|
-
client: EngineClient | NeosClient | None = None,
|
|
60
|
-
model: Model | None = None,
|
|
61
|
-
load_symbols: list[Symbol] | None = None,
|
|
62
|
-
) -> Local | GAMSEngine | NEOSServer:
|
|
63
|
-
if backend == "neos":
|
|
64
|
-
from gamspy._backend.neos import NEOSServer
|
|
65
|
-
|
|
66
|
-
return NEOSServer(
|
|
67
|
-
container,
|
|
68
|
-
options,
|
|
69
|
-
solver,
|
|
70
|
-
solver_options,
|
|
71
|
-
client,
|
|
72
|
-
output,
|
|
73
|
-
model,
|
|
74
|
-
load_symbols,
|
|
75
|
-
)
|
|
76
|
-
elif backend == "engine":
|
|
77
|
-
from gamspy._backend.engine import GAMSEngine
|
|
78
|
-
|
|
79
|
-
return GAMSEngine(
|
|
80
|
-
container,
|
|
81
|
-
client,
|
|
82
|
-
options,
|
|
83
|
-
solver,
|
|
84
|
-
solver_options,
|
|
85
|
-
output,
|
|
86
|
-
model,
|
|
87
|
-
load_symbols,
|
|
88
|
-
)
|
|
89
|
-
elif backend == "local":
|
|
90
|
-
from gamspy._backend.local import Local
|
|
91
|
-
|
|
92
|
-
return Local(
|
|
93
|
-
container,
|
|
94
|
-
options,
|
|
95
|
-
solver,
|
|
96
|
-
solver_options,
|
|
97
|
-
output,
|
|
98
|
-
model,
|
|
99
|
-
load_symbols,
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
raise ValidationError(
|
|
103
|
-
f"`{backend}` is not a valid backend. Possible backends:"
|
|
104
|
-
" local, engine, and neos"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def _cast_values(
|
|
109
|
-
objective_value: str,
|
|
110
|
-
num_equations: str,
|
|
111
|
-
num_variables: str,
|
|
112
|
-
solver_time: str,
|
|
113
|
-
) -> tuple[float, int | float, int | float, float]:
|
|
114
|
-
objective = float("nan") if objective_value == "NA" else float(objective_value)
|
|
115
|
-
equations = float("nan") if num_equations == "NA" else int(num_equations)
|
|
116
|
-
variables = float("nan") if num_variables == "NA" else int(num_variables)
|
|
117
|
-
time = float("nan") if solver_time == "NA" else float(solver_time)
|
|
118
|
-
|
|
119
|
-
return objective, equations, variables, time
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
class Backend(ABC):
|
|
123
|
-
def __init__(
|
|
124
|
-
self,
|
|
125
|
-
backend_type: str,
|
|
126
|
-
container: Container,
|
|
127
|
-
model: Model | None,
|
|
128
|
-
options: Options,
|
|
129
|
-
solver: str | None,
|
|
130
|
-
solver_options: dict | Path | None,
|
|
131
|
-
output: io.TextIOWrapper | None,
|
|
132
|
-
load_symbols: list[Symbol] | None,
|
|
133
|
-
):
|
|
134
|
-
self.backend_type = backend_type
|
|
135
|
-
self.container = container
|
|
136
|
-
self.model = model
|
|
137
|
-
self.options = options
|
|
138
|
-
self.solver = solver
|
|
139
|
-
self.solver_options = solver_options
|
|
140
|
-
self.output = output
|
|
141
|
-
if load_symbols is not None:
|
|
142
|
-
self.load_symbols: list[str] = [
|
|
143
|
-
symbol.name # type: ignore
|
|
144
|
-
for symbol in load_symbols
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
self.job_name = self.get_job_name()
|
|
148
|
-
self.gms_file = self.job_name + ".gms"
|
|
149
|
-
self.lst_file = self.job_name + ".lst"
|
|
150
|
-
self.pf_file = self.job_name + ".pf"
|
|
151
|
-
self.restart_file = self.job_name + ".g00"
|
|
152
|
-
self.trace_file = self.job_name + ".txt"
|
|
153
|
-
|
|
154
|
-
@abstractmethod
|
|
155
|
-
def is_async(self): ...
|
|
156
|
-
|
|
157
|
-
@abstractmethod
|
|
158
|
-
def run(
|
|
159
|
-
self,
|
|
160
|
-
relaxed_domain_mapping: bool = False,
|
|
161
|
-
gams_to_gamspy: bool = False,
|
|
162
|
-
): ...
|
|
163
|
-
|
|
164
|
-
def get_job_name(self):
|
|
165
|
-
job_name = self.container._job
|
|
166
|
-
|
|
167
|
-
if self.container._debugging_level == "keep":
|
|
168
|
-
job_name = os.path.join(
|
|
169
|
-
self.container.working_directory,
|
|
170
|
-
"_" + utils._get_unique_name(),
|
|
171
|
-
)
|
|
172
|
-
self.container._job = job_name
|
|
173
|
-
self.container._gdx_in = f"{job_name}in.gdx"
|
|
174
|
-
self.container._gdx_out = f"{job_name}out.gdx"
|
|
175
|
-
|
|
176
|
-
return job_name
|
|
177
|
-
|
|
178
|
-
def preprocess(self):
|
|
179
|
-
modified_names = self.container._get_modified_symbols()
|
|
180
|
-
|
|
181
|
-
if len(modified_names) != 0:
|
|
182
|
-
try:
|
|
183
|
-
self.container.write(
|
|
184
|
-
self.container._gdx_in, modified_names, eps_to_zero=False
|
|
185
|
-
)
|
|
186
|
-
except Exception as e:
|
|
187
|
-
# Unfortunately, GTP raises a blind exception here. Turn it into a GamspyException.
|
|
188
|
-
raise GamspyException(str(e)) from e
|
|
189
|
-
|
|
190
|
-
gdx_in = self.container._gdx_in
|
|
191
|
-
if self.backend_type == "engine":
|
|
192
|
-
gdx_in = os.path.basename(gdx_in)
|
|
193
|
-
elif self.backend_type == "neos":
|
|
194
|
-
gdx_in = "in.gdx"
|
|
195
|
-
gams_string = self.container._generate_gams_string(gdx_in, modified_names)
|
|
196
|
-
self.make_unmodified(modified_names)
|
|
197
|
-
|
|
198
|
-
return gams_string
|
|
199
|
-
|
|
200
|
-
def load_records(self, relaxed_domain_mapping: bool = False):
|
|
201
|
-
if hasattr(self, "load_symbols"):
|
|
202
|
-
symbols = self.load_symbols
|
|
203
|
-
else:
|
|
204
|
-
symbols = utils._get_symbol_names_from_gdx(
|
|
205
|
-
self.container.system_directory, self.container._gdx_out
|
|
206
|
-
)
|
|
207
|
-
filtered_names = []
|
|
208
|
-
for name in symbols:
|
|
209
|
-
# addGamsCode symbols
|
|
210
|
-
if name not in self.container:
|
|
211
|
-
filtered_names.append(name)
|
|
212
|
-
continue
|
|
213
|
-
|
|
214
|
-
symbol = self.container[name]
|
|
215
|
-
if type(symbol) is syms.Alias:
|
|
216
|
-
filtered_names.append(name)
|
|
217
|
-
continue
|
|
218
|
-
|
|
219
|
-
if symbol.synchronize:
|
|
220
|
-
filtered_names.append(name)
|
|
221
|
-
|
|
222
|
-
symbols = filtered_names
|
|
223
|
-
|
|
224
|
-
if len(symbols) != 0:
|
|
225
|
-
self.container._load_records_from_gdx(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
new_domain.append(elem)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
_,
|
|
269
|
-
_,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
_,
|
|
275
|
-
_,
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
_,
|
|
282
|
-
|
|
283
|
-
_,
|
|
284
|
-
_,
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from abc import ABC, abstractmethod
|
|
5
|
+
from typing import TYPE_CHECKING, Literal, no_type_check
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
|
|
9
|
+
import gamspy._symbols as syms
|
|
10
|
+
import gamspy.utils as utils
|
|
11
|
+
from gamspy.exceptions import GamspyException, ValidationError
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
import io
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from gamspy import Container, Model, Options
|
|
18
|
+
from gamspy._backend.engine import EngineClient, GAMSEngine
|
|
19
|
+
from gamspy._backend.local import Local
|
|
20
|
+
from gamspy._backend.neos import NeosClient, NEOSServer
|
|
21
|
+
from gamspy._symbols.symbol import Symbol
|
|
22
|
+
|
|
23
|
+
SOLVE_STATUS = [
|
|
24
|
+
"",
|
|
25
|
+
"Normal",
|
|
26
|
+
"Iteration",
|
|
27
|
+
"Resource",
|
|
28
|
+
"Solver",
|
|
29
|
+
"EvalError",
|
|
30
|
+
"Capability",
|
|
31
|
+
"License",
|
|
32
|
+
"User",
|
|
33
|
+
"SetupErr",
|
|
34
|
+
"SolverErr",
|
|
35
|
+
"InternalErr",
|
|
36
|
+
"Skipped",
|
|
37
|
+
"SystemErr",
|
|
38
|
+
]
|
|
39
|
+
HEADER = [
|
|
40
|
+
"Solver Status",
|
|
41
|
+
"Model Status",
|
|
42
|
+
"Objective",
|
|
43
|
+
"Num of Equations",
|
|
44
|
+
"Num of Variables",
|
|
45
|
+
"Model Type",
|
|
46
|
+
"Solver",
|
|
47
|
+
"Solver Time",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@no_type_check
|
|
52
|
+
def backend_factory(
|
|
53
|
+
container: Container,
|
|
54
|
+
options: Options | None = None,
|
|
55
|
+
solver: str | None = None,
|
|
56
|
+
solver_options: dict | Path | None = None,
|
|
57
|
+
output: io.TextIOWrapper | None = None,
|
|
58
|
+
backend: Literal["local", "engine", "neos"] = "local",
|
|
59
|
+
client: EngineClient | NeosClient | None = None,
|
|
60
|
+
model: Model | None = None,
|
|
61
|
+
load_symbols: list[Symbol] | None = None,
|
|
62
|
+
) -> Local | GAMSEngine | NEOSServer:
|
|
63
|
+
if backend == "neos":
|
|
64
|
+
from gamspy._backend.neos import NEOSServer
|
|
65
|
+
|
|
66
|
+
return NEOSServer(
|
|
67
|
+
container,
|
|
68
|
+
options,
|
|
69
|
+
solver,
|
|
70
|
+
solver_options,
|
|
71
|
+
client,
|
|
72
|
+
output,
|
|
73
|
+
model,
|
|
74
|
+
load_symbols,
|
|
75
|
+
)
|
|
76
|
+
elif backend == "engine":
|
|
77
|
+
from gamspy._backend.engine import GAMSEngine
|
|
78
|
+
|
|
79
|
+
return GAMSEngine(
|
|
80
|
+
container,
|
|
81
|
+
client,
|
|
82
|
+
options,
|
|
83
|
+
solver,
|
|
84
|
+
solver_options,
|
|
85
|
+
output,
|
|
86
|
+
model,
|
|
87
|
+
load_symbols,
|
|
88
|
+
)
|
|
89
|
+
elif backend == "local":
|
|
90
|
+
from gamspy._backend.local import Local
|
|
91
|
+
|
|
92
|
+
return Local(
|
|
93
|
+
container,
|
|
94
|
+
options,
|
|
95
|
+
solver,
|
|
96
|
+
solver_options,
|
|
97
|
+
output,
|
|
98
|
+
model,
|
|
99
|
+
load_symbols,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
raise ValidationError(
|
|
103
|
+
f"`{backend}` is not a valid backend. Possible backends:"
|
|
104
|
+
" local, engine, and neos"
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _cast_values(
|
|
109
|
+
objective_value: str,
|
|
110
|
+
num_equations: str,
|
|
111
|
+
num_variables: str,
|
|
112
|
+
solver_time: str,
|
|
113
|
+
) -> tuple[float, int | float, int | float, float]:
|
|
114
|
+
objective = float("nan") if objective_value == "NA" else float(objective_value)
|
|
115
|
+
equations = float("nan") if num_equations == "NA" else int(num_equations)
|
|
116
|
+
variables = float("nan") if num_variables == "NA" else int(num_variables)
|
|
117
|
+
time = float("nan") if solver_time == "NA" else float(solver_time)
|
|
118
|
+
|
|
119
|
+
return objective, equations, variables, time
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class Backend(ABC):
|
|
123
|
+
def __init__(
|
|
124
|
+
self,
|
|
125
|
+
backend_type: str,
|
|
126
|
+
container: Container,
|
|
127
|
+
model: Model | None,
|
|
128
|
+
options: Options,
|
|
129
|
+
solver: str | None,
|
|
130
|
+
solver_options: dict | Path | None,
|
|
131
|
+
output: io.TextIOWrapper | None,
|
|
132
|
+
load_symbols: list[Symbol] | None,
|
|
133
|
+
):
|
|
134
|
+
self.backend_type = backend_type
|
|
135
|
+
self.container = container
|
|
136
|
+
self.model = model
|
|
137
|
+
self.options = options
|
|
138
|
+
self.solver = solver
|
|
139
|
+
self.solver_options = solver_options
|
|
140
|
+
self.output = output
|
|
141
|
+
if load_symbols is not None:
|
|
142
|
+
self.load_symbols: list[str] = [
|
|
143
|
+
symbol.name # type: ignore
|
|
144
|
+
for symbol in load_symbols
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
self.job_name = self.get_job_name()
|
|
148
|
+
self.gms_file = self.job_name + ".gms"
|
|
149
|
+
self.lst_file = self.job_name + ".lst"
|
|
150
|
+
self.pf_file = self.job_name + ".pf"
|
|
151
|
+
self.restart_file = self.job_name + ".g00"
|
|
152
|
+
self.trace_file = self.job_name + ".txt"
|
|
153
|
+
|
|
154
|
+
@abstractmethod
|
|
155
|
+
def is_async(self): ...
|
|
156
|
+
|
|
157
|
+
@abstractmethod
|
|
158
|
+
def run(
|
|
159
|
+
self,
|
|
160
|
+
relaxed_domain_mapping: bool = False,
|
|
161
|
+
gams_to_gamspy: bool = False,
|
|
162
|
+
): ...
|
|
163
|
+
|
|
164
|
+
def get_job_name(self):
|
|
165
|
+
job_name = self.container._job
|
|
166
|
+
|
|
167
|
+
if self.container._debugging_level == "keep":
|
|
168
|
+
job_name = os.path.join(
|
|
169
|
+
self.container.working_directory,
|
|
170
|
+
"_" + utils._get_unique_name(),
|
|
171
|
+
)
|
|
172
|
+
self.container._job = job_name
|
|
173
|
+
self.container._gdx_in = f"{job_name}in.gdx"
|
|
174
|
+
self.container._gdx_out = f"{job_name}out.gdx"
|
|
175
|
+
|
|
176
|
+
return job_name
|
|
177
|
+
|
|
178
|
+
def preprocess(self):
|
|
179
|
+
modified_names = self.container._get_modified_symbols()
|
|
180
|
+
|
|
181
|
+
if len(modified_names) != 0:
|
|
182
|
+
try:
|
|
183
|
+
self.container.write(
|
|
184
|
+
self.container._gdx_in, modified_names, eps_to_zero=False
|
|
185
|
+
)
|
|
186
|
+
except Exception as e:
|
|
187
|
+
# Unfortunately, GTP raises a blind exception here. Turn it into a GamspyException.
|
|
188
|
+
raise GamspyException(str(e)) from e
|
|
189
|
+
|
|
190
|
+
gdx_in = self.container._gdx_in
|
|
191
|
+
if self.backend_type == "engine":
|
|
192
|
+
gdx_in = os.path.basename(gdx_in)
|
|
193
|
+
elif self.backend_type == "neos":
|
|
194
|
+
gdx_in = "in.gdx"
|
|
195
|
+
gams_string = self.container._generate_gams_string(gdx_in, modified_names)
|
|
196
|
+
self.make_unmodified(modified_names)
|
|
197
|
+
|
|
198
|
+
return gams_string
|
|
199
|
+
|
|
200
|
+
def load_records(self, relaxed_domain_mapping: bool = False):
|
|
201
|
+
if hasattr(self, "load_symbols"):
|
|
202
|
+
symbols = self.load_symbols
|
|
203
|
+
else:
|
|
204
|
+
symbols = utils._get_symbol_names_from_gdx(
|
|
205
|
+
self.container.system_directory, self.container._gdx_out
|
|
206
|
+
)
|
|
207
|
+
filtered_names = []
|
|
208
|
+
for name in symbols:
|
|
209
|
+
# addGamsCode symbols
|
|
210
|
+
if name not in self.container:
|
|
211
|
+
filtered_names.append(name)
|
|
212
|
+
continue
|
|
213
|
+
|
|
214
|
+
symbol = self.container[name]
|
|
215
|
+
if type(symbol) is syms.Alias:
|
|
216
|
+
filtered_names.append(name)
|
|
217
|
+
continue
|
|
218
|
+
|
|
219
|
+
if symbol.synchronize:
|
|
220
|
+
filtered_names.append(name)
|
|
221
|
+
|
|
222
|
+
symbols = filtered_names
|
|
223
|
+
|
|
224
|
+
if len(symbols) != 0:
|
|
225
|
+
self.container._load_records_from_gdx(
|
|
226
|
+
self.container._gdx_out, symbols, create_if_not_declared=True
|
|
227
|
+
)
|
|
228
|
+
self.make_unmodified(symbols)
|
|
229
|
+
|
|
230
|
+
if relaxed_domain_mapping:
|
|
231
|
+
# Best attempt approach to map relaxed domain to actual symbols
|
|
232
|
+
for name in symbols:
|
|
233
|
+
symbol = self.container[name]
|
|
234
|
+
|
|
235
|
+
new_domain = []
|
|
236
|
+
for elem in symbol.domain:
|
|
237
|
+
if type(elem) is str and elem != "*" and elem in self.container:
|
|
238
|
+
new_domain.append(self.container[elem])
|
|
239
|
+
else:
|
|
240
|
+
new_domain.append(elem)
|
|
241
|
+
|
|
242
|
+
symbol.domain = new_domain
|
|
243
|
+
symbol.dimension = len(new_domain)
|
|
244
|
+
if type(symbol) in (syms.Variable, syms.Equation):
|
|
245
|
+
symbol._update_attr_domains()
|
|
246
|
+
|
|
247
|
+
def parse_listings(self):
|
|
248
|
+
listing_file = (
|
|
249
|
+
self.options.listing_file
|
|
250
|
+
if self.options.listing_file
|
|
251
|
+
else self.job_name + ".lst"
|
|
252
|
+
)
|
|
253
|
+
if self.options.equation_listing_limit:
|
|
254
|
+
utils._parse_generated_equations(self.model, listing_file)
|
|
255
|
+
|
|
256
|
+
if self.options.variable_listing_limit:
|
|
257
|
+
utils._parse_generated_variables(self.model, listing_file)
|
|
258
|
+
|
|
259
|
+
def prepare_summary(self, trace_file: str) -> pd.DataFrame:
|
|
260
|
+
from gamspy._model import ModelStatus
|
|
261
|
+
|
|
262
|
+
with open(trace_file, encoding="utf-8") as file:
|
|
263
|
+
line = file.readlines()[-1]
|
|
264
|
+
(
|
|
265
|
+
_,
|
|
266
|
+
model_type,
|
|
267
|
+
solver_name,
|
|
268
|
+
_,
|
|
269
|
+
_,
|
|
270
|
+
_,
|
|
271
|
+
_,
|
|
272
|
+
num_equations,
|
|
273
|
+
num_variables,
|
|
274
|
+
_,
|
|
275
|
+
_,
|
|
276
|
+
_,
|
|
277
|
+
_,
|
|
278
|
+
model_status,
|
|
279
|
+
solver_status,
|
|
280
|
+
objective_value,
|
|
281
|
+
_,
|
|
282
|
+
solver_time,
|
|
283
|
+
_,
|
|
284
|
+
_,
|
|
285
|
+
_,
|
|
286
|
+
_,
|
|
287
|
+
) = line.split(",")
|
|
288
|
+
|
|
289
|
+
objective_value, num_equations, num_variables, solver_time = _cast_values(
|
|
290
|
+
objective_value, num_equations, num_variables, solver_time
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
dataframe = pd.DataFrame(
|
|
294
|
+
[
|
|
295
|
+
[
|
|
296
|
+
SOLVE_STATUS[int(solver_status)],
|
|
297
|
+
ModelStatus(int(model_status)).name,
|
|
298
|
+
objective_value,
|
|
299
|
+
num_equations,
|
|
300
|
+
num_variables,
|
|
301
|
+
model_type,
|
|
302
|
+
solver_name,
|
|
303
|
+
solver_time,
|
|
304
|
+
]
|
|
305
|
+
],
|
|
306
|
+
columns=HEADER,
|
|
307
|
+
)
|
|
308
|
+
return dataframe
|
|
309
|
+
|
|
310
|
+
def make_unmodified(self, modified_names: list[str]):
|
|
311
|
+
for name in modified_names:
|
|
312
|
+
if not name.startswith("autogenerated_"):
|
|
313
|
+
self.container[name].modified = False
|