gamspy 1.16.0__tar.gz → 1.17.1__tar.gz
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-1.16.0 → gamspy-1.17.1}/PKG-INFO +10 -9
- {gamspy-1.16.0 → gamspy-1.17.1}/README.md +1 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/README_PYPI.md +1 -1
- {gamspy-1.16.0 → gamspy-1.17.1}/pyproject.toml +26 -31
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/__init__.py +1 -1
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/condition.py +1 -3
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/domain.py +1 -3
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/expression.py +21 -44
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/operable.py +20 -24
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/operation.py +14 -58
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/backend.py +6 -18
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/engine.py +103 -141
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/neos.py +8 -23
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/cli.py +4 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/gdx.py +142 -41
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/install.py +89 -54
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/list.py +9 -13
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/probe.py +10 -8
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/retrieve.py +11 -15
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/run.py +37 -42
- gamspy-1.17.1/src/gamspy/_cli/show.py +255 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/uninstall.py +47 -23
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/util.py +3 -7
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_config.py +3 -5
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_container.py +50 -56
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_convert.py +33 -59
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_database.py +3 -7
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_extrinsic.py +4 -12
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_miro.py +14 -34
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_model.py +64 -59
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_model_instance.py +21 -55
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_options.py +115 -120
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_serialization.py +9 -8
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/alias.py +8 -12
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/equation.py +12 -20
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_equation.py +2 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_parameter.py +6 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_set.py +6 -11
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_symbol.py +14 -20
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/implicit_variable.py +7 -10
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/parameter.py +15 -37
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/set.py +18 -50
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/symbol.py +19 -19
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/universe_alias.py +7 -18
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/variable.py +18 -42
- gamspy-1.17.1/src/gamspy/_types.py +7 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_validation.py +20 -49
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_workspace.py +2 -7
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/exceptions.py +2 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/__init__.py +12 -10
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/decision_tree_struct.py +5 -17
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/gradient_boosting.py +5 -13
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/random_forest.py +4 -10
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/regression_tree.py +19 -48
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/avgpool2d.py +6 -18
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/conv1d.py +12 -39
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/conv2d.py +17 -39
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/linear.py +7 -23
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/maxpool2d.py +6 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/minpool2d.py +6 -4
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/mpool2d.py +9 -23
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/torch_sequential.py +13 -39
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/piecewise.py +18 -45
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/shape.py +2 -6
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/utils.py +6 -19
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/__init__.py +68 -66
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/activation.py +74 -18
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/matrix.py +9 -22
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/misc.py +4 -10
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/utils.py +62 -109
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/PKG-INFO +10 -9
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/requires.txt +7 -6
- {gamspy-1.16.0 → gamspy-1.17.1}/tests/test_gamspy.py +4 -24
- gamspy-1.16.0/src/gamspy/_cli/show.py +0 -46
- gamspy-1.16.0/src/gamspy/_types.py +0 -10
- {gamspy-1.16.0 → gamspy-1.17.1}/LICENSE +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/setup.cfg +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/__main__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/__init__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_algebra/number.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/__init__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_backend/local.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_cli/__init__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/__init__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/_symbols/implicits/__init__.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/ml/__init__.py +2 -2
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/formulations/nn/__init__.py +3 -3
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/log_power.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/probability.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/math/trigonometric.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/py.typed +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy/version.py +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/SOURCES.txt +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/dependency_links.txt +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/entry_points.txt +0 -0
- {gamspy-1.16.0 → gamspy-1.17.1}/src/gamspy.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gamspy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.17.1
|
|
4
4
|
Summary: Python-based algebraic modeling interface to GAMS
|
|
5
5
|
Author-email: GAMS Development Corporation <support@gams.com>
|
|
6
6
|
Project-URL: homepage, https://gams.com/sales/gamspy_facts/
|
|
@@ -28,19 +28,20 @@ Classifier: Operating System :: POSIX
|
|
|
28
28
|
Classifier: Operating System :: Unix
|
|
29
29
|
Classifier: Operating System :: MacOS
|
|
30
30
|
Classifier: Operating System :: Microsoft :: Windows
|
|
31
|
-
Requires-Python: >=3.
|
|
31
|
+
Requires-Python: >=3.10
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
License-File: LICENSE
|
|
34
|
-
Requires-Dist: gamsapi
|
|
35
|
-
Requires-Dist: gamspy_base
|
|
34
|
+
Requires-Dist: gamsapi<52.0.0,>=51.1.0
|
|
35
|
+
Requires-Dist: gamspy_base<52.0.0,>=51.1.0
|
|
36
|
+
Requires-Dist: pandas<2.4,>=2.2.2
|
|
36
37
|
Requires-Dist: pydantic>=2.0
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist: urllib3>=2.0.7
|
|
38
|
+
Requires-Dist: requests>=2.28.0
|
|
39
39
|
Requires-Dist: typer>=0.16.0
|
|
40
40
|
Provides-Extra: dev
|
|
41
|
-
Requires-Dist: ruff
|
|
41
|
+
Requires-Dist: ruff>=0.13.0; extra == "dev"
|
|
42
42
|
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
|
|
43
|
-
Requires-Dist: mypy>=1.
|
|
43
|
+
Requires-Dist: mypy>=1.18.1; extra == "dev"
|
|
44
|
+
Requires-Dist: griffe>=1.14.0; extra == "dev"
|
|
44
45
|
Provides-Extra: test
|
|
45
46
|
Requires-Dist: coverage[toml]>=7.2.7; extra == "test"
|
|
46
47
|
Requires-Dist: openpyxl>=3.1.2; extra == "test"
|
|
@@ -117,4 +118,4 @@ Here are just a few of the things that **gamspy** does well:
|
|
|
117
118
|
## Getting Help
|
|
118
119
|
|
|
119
120
|
For usage questions, the best place to go to is [GAMSPy Documentation](https://gamspy.readthedocs.io/en/latest/index.html).
|
|
120
|
-
General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com
|
|
121
|
+
General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com).
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
-----------------
|
|
4
4
|
[](https://gamspy.readthedocs.io/en/latest/)
|
|
5
5
|
[](https://pepy.tech/project/gamspy)
|
|
6
|
+
[](https://pypi.python.org/pypi/gamspy)
|
|
6
7
|
[](https://gamspy.readthedocs.io/en/latest/)
|
|
7
8
|
|
|
8
9
|
# GAMSPy: Algebraic Modeling Interface to GAMS
|
|
@@ -44,4 +44,4 @@ Here are just a few of the things that **gamspy** does well:
|
|
|
44
44
|
## Getting Help
|
|
45
45
|
|
|
46
46
|
For usage questions, the best place to go to is [GAMSPy Documentation](https://gamspy.readthedocs.io/en/latest/index.html).
|
|
47
|
-
General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com
|
|
47
|
+
General questions and discussions can also take place on the [GAMSPy Discourse Platform](https://forum.gams.com).
|
|
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gamspy"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.17.1"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name = "GAMS Development Corporation", email = "support@gams.com" },
|
|
10
10
|
]
|
|
11
11
|
readme = "README_PYPI.md"
|
|
12
12
|
description = "Python-based algebraic modeling interface to GAMS"
|
|
13
|
-
requires-python = ">=3.
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
14
|
license-files = ["LICENSE"]
|
|
15
15
|
keywords = ["Optimization", "GAMS"]
|
|
16
16
|
classifiers = [
|
|
@@ -36,11 +36,11 @@ classifiers = [
|
|
|
36
36
|
"Operating System :: Microsoft :: Windows",
|
|
37
37
|
]
|
|
38
38
|
dependencies = [
|
|
39
|
-
"gamsapi
|
|
40
|
-
"gamspy_base >= 51.1.0",
|
|
39
|
+
"gamsapi >= 51.1.0, < 52.0.0",
|
|
40
|
+
"gamspy_base >= 51.1.0, < 52.0.0",
|
|
41
|
+
"pandas >= 2.2.2, < 2.4",
|
|
41
42
|
"pydantic >= 2.0",
|
|
42
|
-
"
|
|
43
|
-
"urllib3 >= 2.0.7",
|
|
43
|
+
"requests >= 2.28.0",
|
|
44
44
|
"typer >= 0.16.0",
|
|
45
45
|
]
|
|
46
46
|
|
|
@@ -53,9 +53,10 @@ changelog = "https://github.com/GAMS-dev/gamspy/blob/develop/CHANGELOG.md"
|
|
|
53
53
|
|
|
54
54
|
[project.optional-dependencies]
|
|
55
55
|
dev = [
|
|
56
|
-
"ruff
|
|
56
|
+
"ruff >= 0.13.0",
|
|
57
57
|
"pre-commit >= 3.5.0",
|
|
58
|
-
"mypy >= 1.
|
|
58
|
+
"mypy >= 1.18.1",
|
|
59
|
+
"griffe >= 1.14.0",
|
|
59
60
|
]
|
|
60
61
|
|
|
61
62
|
test = [
|
|
@@ -211,37 +212,31 @@ exclude = [
|
|
|
211
212
|
"node_modules",
|
|
212
213
|
"site-packages",
|
|
213
214
|
"venv",
|
|
214
|
-
"_cli",
|
|
215
|
-
"_options.py"
|
|
216
215
|
]
|
|
217
216
|
|
|
218
|
-
# Same as
|
|
219
|
-
line-length =
|
|
217
|
+
# Same as black.
|
|
218
|
+
line-length = 88
|
|
220
219
|
indent-width = 4
|
|
221
220
|
|
|
222
|
-
# Assume Python
|
|
223
|
-
target-version = "
|
|
221
|
+
# Assume Python 3.10
|
|
222
|
+
target-version = "py310"
|
|
224
223
|
|
|
225
224
|
[tool.ruff.lint]
|
|
226
225
|
select = [
|
|
227
|
-
# pycodestyle
|
|
228
|
-
"
|
|
229
|
-
# Pyflakes
|
|
230
|
-
"
|
|
231
|
-
#
|
|
232
|
-
"
|
|
233
|
-
#
|
|
234
|
-
"
|
|
235
|
-
#
|
|
236
|
-
"
|
|
237
|
-
#
|
|
238
|
-
"
|
|
239
|
-
# flake8-pie
|
|
240
|
-
"PIE",
|
|
241
|
-
# Consider merging multiple comparisons
|
|
242
|
-
"PLR1714",
|
|
226
|
+
"E", # pycodestyle error
|
|
227
|
+
"W", # pycodestyle warning
|
|
228
|
+
"F", # Pyflakes
|
|
229
|
+
"UP", # pyupgrade
|
|
230
|
+
"B", # flake8-bugbear
|
|
231
|
+
"SIM", # flake8-simplify
|
|
232
|
+
"I", # isort
|
|
233
|
+
"PIE", # flake8-pie
|
|
234
|
+
"PLR1714", # Consider merging multiple comparisons
|
|
235
|
+
"RUF", # Ruff-specific rules
|
|
236
|
+
"TC", # flake8-type-checking
|
|
237
|
+
"C4", # flake8-comprehensions
|
|
243
238
|
]
|
|
244
|
-
ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006"]
|
|
239
|
+
ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006", "RUF005", "RUF022"]
|
|
245
240
|
|
|
246
241
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
247
242
|
fixable = ["ALL"]
|
|
@@ -96,9 +96,7 @@ class Condition(operable.Operable):
|
|
|
96
96
|
statement = expression.Expression(lhs, op_type, rhs)
|
|
97
97
|
|
|
98
98
|
if isinstance(self.conditioning_on, ImplicitSymbol):
|
|
99
|
-
statement._validate_definition(
|
|
100
|
-
utils._unpack(self.conditioning_on.domain)
|
|
101
|
-
)
|
|
99
|
+
statement._validate_definition(utils._unpack(self.conditioning_on.domain))
|
|
102
100
|
|
|
103
101
|
self.conditioning_on.container._add_statement(statement)
|
|
104
102
|
|
|
@@ -47,9 +47,7 @@ class Domain:
|
|
|
47
47
|
|
|
48
48
|
def _sanity_check(self, sets: tuple[Set | Alias | ImplicitSet, ...]):
|
|
49
49
|
if len(sets) < 2:
|
|
50
|
-
error_message = (
|
|
51
|
-
f"Domain requires at least 2 sets but found {len(sets)}. "
|
|
52
|
-
)
|
|
50
|
+
error_message = f"Domain requires at least 2 sets but found {len(sets)}. "
|
|
53
51
|
if len(sets) == 1:
|
|
54
52
|
error_message += f"You can directly limit the domain with {sets[0].name}.where[<your_limitation>]."
|
|
55
53
|
raise ValidationError(error_message)
|
|
@@ -20,8 +20,6 @@ from gamspy.exceptions import ValidationError
|
|
|
20
20
|
from gamspy.math.misc import MathOp
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
|
-
from numbers import Real
|
|
24
|
-
|
|
25
23
|
import pandas as pd
|
|
26
24
|
|
|
27
25
|
from gamspy import Alias, Set
|
|
@@ -150,7 +148,7 @@ def create_gams_expression(root_node: Expression) -> str:
|
|
|
150
148
|
s1.append(node.right)
|
|
151
149
|
|
|
152
150
|
# 2. Build the GAMS expression
|
|
153
|
-
eval_stack: list[tuple[str,
|
|
151
|
+
eval_stack: list[tuple[str, float]] = []
|
|
154
152
|
for node in reversed(post_order_nodes):
|
|
155
153
|
if not isinstance(node, Expression):
|
|
156
154
|
eval_stack.append((get_operand_gams_repr(node), LEAF_PRECEDENCE))
|
|
@@ -181,14 +179,10 @@ def create_gams_expression(root_node: Expression) -> str:
|
|
|
181
179
|
right_str, right_prec = eval_stack.pop()
|
|
182
180
|
left_str, left_prec = eval_stack.pop()
|
|
183
181
|
|
|
184
|
-
if left_prec < op_prec or (
|
|
185
|
-
left_prec == op_prec and op_assoc == "right"
|
|
186
|
-
):
|
|
182
|
+
if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
|
|
187
183
|
left_str = f"({left_str})"
|
|
188
184
|
|
|
189
|
-
if right_prec < op_prec or (
|
|
190
|
-
right_prec == op_prec and op_assoc == "left"
|
|
191
|
-
):
|
|
185
|
+
if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
|
|
192
186
|
right_str = f"({right_str})"
|
|
193
187
|
|
|
194
188
|
# get around 80000 line length limitation in GAMS
|
|
@@ -241,7 +235,7 @@ def create_latex_expression(root_node: Expression) -> str:
|
|
|
241
235
|
s1.append(node.right)
|
|
242
236
|
|
|
243
237
|
# 2. Build the GAMS expression
|
|
244
|
-
eval_stack: list[tuple[str,
|
|
238
|
+
eval_stack: list[tuple[str, float]] = []
|
|
245
239
|
for node in reversed(post_order_nodes):
|
|
246
240
|
if not isinstance(node, Expression):
|
|
247
241
|
eval_stack.append((get_operand_latex_repr(node), LEAF_PRECEDENCE))
|
|
@@ -272,20 +266,14 @@ def create_latex_expression(root_node: Expression) -> str:
|
|
|
272
266
|
right_str, right_prec = eval_stack.pop()
|
|
273
267
|
left_str, left_prec = eval_stack.pop()
|
|
274
268
|
|
|
275
|
-
if left_prec < op_prec or (
|
|
276
|
-
left_prec == op_prec and op_assoc == "right"
|
|
277
|
-
):
|
|
269
|
+
if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
|
|
278
270
|
left_str = f"({left_str})"
|
|
279
271
|
|
|
280
|
-
if right_prec < op_prec or (
|
|
281
|
-
right_prec == op_prec and op_assoc == "left"
|
|
282
|
-
):
|
|
272
|
+
if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
|
|
283
273
|
right_str = f"({right_str})"
|
|
284
274
|
|
|
285
275
|
if op == "/":
|
|
286
|
-
eval_stack.append(
|
|
287
|
-
(f"\\frac{{{left_str}}}{{{right_str}}}", op_prec)
|
|
288
|
-
)
|
|
276
|
+
eval_stack.append((f"\\frac{{{left_str}}}{{{right_str}}}", op_prec))
|
|
289
277
|
continue
|
|
290
278
|
|
|
291
279
|
op = op_map.get(op, op)
|
|
@@ -334,16 +322,10 @@ class Expression(operable.Operable):
|
|
|
334
322
|
operator: str,
|
|
335
323
|
right: OperableType | str | None,
|
|
336
324
|
):
|
|
337
|
-
self.left = (
|
|
338
|
-
utils._map_special_values(left)
|
|
339
|
-
if isinstance(left, float)
|
|
340
|
-
else left
|
|
341
|
-
)
|
|
325
|
+
self.left = utils._map_special_values(left) if isinstance(left, float) else left
|
|
342
326
|
self.operator = operator
|
|
343
327
|
self.right = (
|
|
344
|
-
utils._map_special_values(right)
|
|
345
|
-
if isinstance(right, float)
|
|
346
|
-
else right
|
|
328
|
+
utils._map_special_values(right) if isinstance(right, float) else right
|
|
347
329
|
)
|
|
348
330
|
|
|
349
331
|
if operator == "=" and isinstance(right, Expression):
|
|
@@ -422,8 +404,8 @@ class Expression(operable.Operable):
|
|
|
422
404
|
|
|
423
405
|
def __getitem__(self, indices):
|
|
424
406
|
indices = validation.validate_domain(self, indices)
|
|
425
|
-
left_domain =
|
|
426
|
-
right_domain =
|
|
407
|
+
left_domain = list(self._left_domain)
|
|
408
|
+
right_domain = list(self._right_domain)
|
|
427
409
|
for i, s in enumerate(indices):
|
|
428
410
|
for lr, pos in self._shadow_domain[i].indices:
|
|
429
411
|
if lr == "l":
|
|
@@ -654,16 +636,16 @@ class Expression(operable.Operable):
|
|
|
654
636
|
symbols.append(node.alias_with.name)
|
|
655
637
|
|
|
656
638
|
symbols.append(node.name)
|
|
657
|
-
stack
|
|
639
|
+
stack.extend(node.domain)
|
|
658
640
|
node = None
|
|
659
641
|
elif isinstance(node, ImplicitSymbol):
|
|
660
642
|
if node.parent.name not in symbols:
|
|
661
643
|
symbols.append(node.parent.name)
|
|
662
|
-
stack
|
|
663
|
-
stack
|
|
644
|
+
stack.extend(node.domain)
|
|
645
|
+
stack.extend(node.container[node.parent.name].domain)
|
|
664
646
|
node = None
|
|
665
647
|
elif isinstance(node, operation.Operation):
|
|
666
|
-
stack
|
|
648
|
+
stack.extend(node.op_domain)
|
|
667
649
|
node = node.rhs
|
|
668
650
|
elif isinstance(node, condition.Condition):
|
|
669
651
|
stack.append(node.conditioning_on)
|
|
@@ -680,10 +662,10 @@ class Expression(operable.Operable):
|
|
|
680
662
|
if isinstance(node.elements[0], Expression):
|
|
681
663
|
node = node.elements[0]
|
|
682
664
|
else:
|
|
683
|
-
stack
|
|
665
|
+
stack.extend(node.elements)
|
|
684
666
|
node = None
|
|
685
667
|
elif isinstance(node, ExtrinsicFunction):
|
|
686
|
-
stack
|
|
668
|
+
stack.extend(list(node.args))
|
|
687
669
|
node = None
|
|
688
670
|
else:
|
|
689
671
|
node = getattr(node, "right", None)
|
|
@@ -708,12 +690,12 @@ class Expression(operable.Operable):
|
|
|
708
690
|
given_condition = node.condition
|
|
709
691
|
|
|
710
692
|
if isinstance(given_condition, Expression):
|
|
711
|
-
symbols
|
|
693
|
+
symbols.extend(given_condition._find_all_symbols())
|
|
712
694
|
elif isinstance(given_condition, ImplicitSymbol):
|
|
713
695
|
symbols.append(given_condition.parent.name)
|
|
714
696
|
|
|
715
697
|
if isinstance(node, operation.Operation):
|
|
716
|
-
stack
|
|
698
|
+
stack.extend(node.op_domain)
|
|
717
699
|
node = node.rhs
|
|
718
700
|
else:
|
|
719
701
|
node = getattr(node, "right", None)
|
|
@@ -725,9 +707,7 @@ class Expression(operable.Operable):
|
|
|
725
707
|
def _validate_definition(
|
|
726
708
|
self, control_stack: list[Set | Alias | ImplicitSet]
|
|
727
709
|
) -> None:
|
|
728
|
-
if not get_option("DOMAIN_VALIDATION") or not get_option(
|
|
729
|
-
"DOMAIN_VALIDATION"
|
|
730
|
-
):
|
|
710
|
+
if not get_option("DOMAIN_VALIDATION") or not get_option("DOMAIN_VALIDATION"):
|
|
731
711
|
return
|
|
732
712
|
|
|
733
713
|
stack = []
|
|
@@ -747,10 +727,7 @@ class Expression(operable.Operable):
|
|
|
747
727
|
if hasattr(elem, "is_singleton") and elem.is_singleton:
|
|
748
728
|
continue
|
|
749
729
|
|
|
750
|
-
if (
|
|
751
|
-
isinstance(elem, Symbol)
|
|
752
|
-
and elem not in control_stack
|
|
753
|
-
):
|
|
730
|
+
if isinstance(elem, Symbol) and elem not in control_stack:
|
|
754
731
|
raise ValidationError(
|
|
755
732
|
f"Uncontrolled set `{elem}` entered as constant!"
|
|
756
733
|
)
|
|
@@ -32,9 +32,9 @@ class Operable:
|
|
|
32
32
|
):
|
|
33
33
|
return self.lead(other)
|
|
34
34
|
|
|
35
|
-
if isinstance(
|
|
36
|
-
|
|
37
|
-
)
|
|
35
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
36
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
37
|
+
):
|
|
38
38
|
return expression.SetExpression(self, "+", other)
|
|
39
39
|
|
|
40
40
|
return expression.Expression(self, "+", other)
|
|
@@ -42,9 +42,9 @@ class Operable:
|
|
|
42
42
|
def __radd__(self, other: OperableType):
|
|
43
43
|
from gamspy._symbols.implicits import ImplicitSet
|
|
44
44
|
|
|
45
|
-
if isinstance(
|
|
46
|
-
|
|
47
|
-
)
|
|
45
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
46
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
47
|
+
):
|
|
48
48
|
return expression.SetExpression(other, "+", self)
|
|
49
49
|
|
|
50
50
|
return expression.Expression(other, "+", self)
|
|
@@ -58,9 +58,9 @@ class Operable:
|
|
|
58
58
|
):
|
|
59
59
|
return self.lag(other)
|
|
60
60
|
|
|
61
|
-
if isinstance(
|
|
62
|
-
|
|
63
|
-
)
|
|
61
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
62
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
63
|
+
):
|
|
64
64
|
return expression.SetExpression(self, "-", other)
|
|
65
65
|
|
|
66
66
|
return expression.Expression(self, "-", other)
|
|
@@ -68,9 +68,9 @@ class Operable:
|
|
|
68
68
|
def __rsub__(self, other: OperableType):
|
|
69
69
|
from gamspy._symbols.implicits import ImplicitSet
|
|
70
70
|
|
|
71
|
-
if isinstance(
|
|
72
|
-
|
|
73
|
-
)
|
|
71
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
72
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
73
|
+
):
|
|
74
74
|
return expression.SetExpression(other, "-", self)
|
|
75
75
|
|
|
76
76
|
return expression.Expression(other, "-", self)
|
|
@@ -87,9 +87,9 @@ class Operable:
|
|
|
87
87
|
def __mul__(self, other: OperableType):
|
|
88
88
|
from gamspy._symbols.implicits import ImplicitSet
|
|
89
89
|
|
|
90
|
-
if isinstance(
|
|
91
|
-
|
|
92
|
-
)
|
|
90
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
91
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
92
|
+
):
|
|
93
93
|
return expression.SetExpression(self, "*", other)
|
|
94
94
|
|
|
95
95
|
return expression.Expression(self, "*", other)
|
|
@@ -97,9 +97,9 @@ class Operable:
|
|
|
97
97
|
def __rmul__(self, other: OperableType):
|
|
98
98
|
from gamspy._symbols.implicits import ImplicitSet
|
|
99
99
|
|
|
100
|
-
if isinstance(
|
|
101
|
-
|
|
102
|
-
)
|
|
100
|
+
if isinstance(self, (ImplicitSet, expression.SetExpression)) or isinstance(
|
|
101
|
+
other, (ImplicitSet, expression.SetExpression)
|
|
102
|
+
):
|
|
103
103
|
return expression.SetExpression(other, "*", self)
|
|
104
104
|
|
|
105
105
|
return expression.Expression(other, "*", self)
|
|
@@ -178,12 +178,8 @@ class Operable:
|
|
|
178
178
|
import gamspy._algebra.operation as operation
|
|
179
179
|
from gamspy.math.matrix import _validate_matrix_mult_dims
|
|
180
180
|
|
|
181
|
-
left_domain, right_domain, sum_domain = _validate_matrix_mult_dims(
|
|
182
|
-
|
|
183
|
-
)
|
|
184
|
-
return operation.Sum(
|
|
185
|
-
[sum_domain], self[left_domain] * other[right_domain]
|
|
186
|
-
)
|
|
181
|
+
left_domain, right_domain, sum_domain = _validate_matrix_mult_dims(self, other)
|
|
182
|
+
return operation.Sum([sum_domain], self[left_domain] * other[right_domain])
|
|
187
183
|
|
|
188
184
|
def gamsRepr(self):
|
|
189
185
|
"""Representation of the symbol in GAMS"""
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from collections.abc import Sequence
|
|
4
3
|
from typing import TYPE_CHECKING
|
|
5
4
|
|
|
6
5
|
import gamspy._algebra.condition as condition
|
|
@@ -14,6 +13,8 @@ import gamspy.utils as utils
|
|
|
14
13
|
from gamspy.exceptions import ValidationError
|
|
15
14
|
|
|
16
15
|
if TYPE_CHECKING:
|
|
16
|
+
from collections.abc import Sequence
|
|
17
|
+
|
|
17
18
|
import pandas as pd
|
|
18
19
|
|
|
19
20
|
from gamspy._algebra import Domain
|
|
@@ -31,12 +32,7 @@ if TYPE_CHECKING:
|
|
|
31
32
|
class Operation(operable.Operable):
|
|
32
33
|
def __init__(
|
|
33
34
|
self,
|
|
34
|
-
domain: Set
|
|
35
|
-
| Alias
|
|
36
|
-
| ImplicitSet
|
|
37
|
-
| Sequence[Set | Alias]
|
|
38
|
-
| Domain
|
|
39
|
-
| Condition,
|
|
35
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
40
36
|
rhs: (
|
|
41
37
|
Expression
|
|
42
38
|
| Operation
|
|
@@ -75,7 +71,7 @@ class Operation(operable.Operable):
|
|
|
75
71
|
self.domain.append(x)
|
|
76
72
|
|
|
77
73
|
self.dimension: int = validation.get_dimension(self.domain)
|
|
78
|
-
controlled_domain =
|
|
74
|
+
controlled_domain = list(self._bare_op_domain)
|
|
79
75
|
controlled_domain.extend(getattr(rhs, "controlled_domain", []))
|
|
80
76
|
self.controlled_domain = list(set(controlled_domain))
|
|
81
77
|
|
|
@@ -160,9 +156,7 @@ class Operation(operable.Operable):
|
|
|
160
156
|
for elem in self.raw_domain:
|
|
161
157
|
if isinstance(elem, implicits.ImplicitSet):
|
|
162
158
|
control_stack += [
|
|
163
|
-
member
|
|
164
|
-
for member in elem.domain
|
|
165
|
-
if member not in control_stack
|
|
159
|
+
member for member in elem.domain if member not in control_stack
|
|
166
160
|
] + [elem.parent]
|
|
167
161
|
|
|
168
162
|
if elem in control_stack:
|
|
@@ -178,11 +172,7 @@ class Operation(operable.Operable):
|
|
|
178
172
|
if len(self.op_domain) == 1:
|
|
179
173
|
return self.op_domain[0].gamsRepr()
|
|
180
174
|
|
|
181
|
-
return (
|
|
182
|
-
"("
|
|
183
|
-
+ ",".join([index.gamsRepr() for index in self.op_domain])
|
|
184
|
-
+ ")"
|
|
185
|
-
)
|
|
175
|
+
return "(" + ",".join([index.gamsRepr() for index in self.op_domain]) + ")"
|
|
186
176
|
|
|
187
177
|
def __eq__(self, other):
|
|
188
178
|
return expression.Expression(self, "=e=", other)
|
|
@@ -266,9 +256,7 @@ class Operation(operable.Operable):
|
|
|
266
256
|
if isinstance(self.rhs, (int, float, str))
|
|
267
257
|
else self.rhs.latexRepr()
|
|
268
258
|
)
|
|
269
|
-
representation =
|
|
270
|
-
f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
|
|
271
|
-
)
|
|
259
|
+
representation = f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
|
|
272
260
|
return representation
|
|
273
261
|
|
|
274
262
|
|
|
@@ -305,12 +293,7 @@ class Sum(Operation):
|
|
|
305
293
|
|
|
306
294
|
def __init__(
|
|
307
295
|
self,
|
|
308
|
-
domain: Set
|
|
309
|
-
| Alias
|
|
310
|
-
| ImplicitSet
|
|
311
|
-
| Sequence[Set | Alias]
|
|
312
|
-
| Domain
|
|
313
|
-
| Condition,
|
|
296
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
314
297
|
expression: Operation
|
|
315
298
|
| Expression
|
|
316
299
|
| MathOp
|
|
@@ -381,12 +364,7 @@ class Product(Operation):
|
|
|
381
364
|
|
|
382
365
|
def __init__(
|
|
383
366
|
self,
|
|
384
|
-
domain: Set
|
|
385
|
-
| Alias
|
|
386
|
-
| ImplicitSet
|
|
387
|
-
| Sequence[Set | Alias]
|
|
388
|
-
| Domain
|
|
389
|
-
| Condition,
|
|
367
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
390
368
|
expression: Operation
|
|
391
369
|
| Expression
|
|
392
370
|
| MathOp
|
|
@@ -457,12 +435,7 @@ class Smin(Operation):
|
|
|
457
435
|
|
|
458
436
|
def __init__(
|
|
459
437
|
self,
|
|
460
|
-
domain: Set
|
|
461
|
-
| Alias
|
|
462
|
-
| ImplicitSet
|
|
463
|
-
| Sequence[Set | Alias]
|
|
464
|
-
| Domain
|
|
465
|
-
| Condition,
|
|
438
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
466
439
|
expression: Operation
|
|
467
440
|
| Expression
|
|
468
441
|
| MathOp
|
|
@@ -533,12 +506,7 @@ class Smax(Operation):
|
|
|
533
506
|
|
|
534
507
|
def __init__(
|
|
535
508
|
self,
|
|
536
|
-
domain: Set
|
|
537
|
-
| Alias
|
|
538
|
-
| ImplicitSet
|
|
539
|
-
| Sequence[Set | Alias]
|
|
540
|
-
| Domain
|
|
541
|
-
| Condition,
|
|
509
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
542
510
|
expression: Operation
|
|
543
511
|
| Expression
|
|
544
512
|
| MathOp
|
|
@@ -609,12 +577,7 @@ class Sand(Operation):
|
|
|
609
577
|
|
|
610
578
|
def __init__(
|
|
611
579
|
self,
|
|
612
|
-
domain: Set
|
|
613
|
-
| Alias
|
|
614
|
-
| ImplicitSet
|
|
615
|
-
| Sequence[Set | Alias]
|
|
616
|
-
| Domain
|
|
617
|
-
| Condition,
|
|
580
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
618
581
|
expression: Operation
|
|
619
582
|
| Expression
|
|
620
583
|
| MathOp
|
|
@@ -684,12 +647,7 @@ class Sor(Operation):
|
|
|
684
647
|
|
|
685
648
|
def __init__(
|
|
686
649
|
self,
|
|
687
|
-
domain: Set
|
|
688
|
-
| Alias
|
|
689
|
-
| ImplicitSet
|
|
690
|
-
| Sequence[Set | Alias]
|
|
691
|
-
| Domain
|
|
692
|
-
| Condition,
|
|
650
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
693
651
|
expression: Operation
|
|
694
652
|
| Expression
|
|
695
653
|
| MathOp
|
|
@@ -746,9 +704,7 @@ class Ord(operable.Operable):
|
|
|
746
704
|
|
|
747
705
|
def __new__(cls, symbol: Set | Alias):
|
|
748
706
|
if not isinstance(symbol, (syms.Set, syms.Alias)):
|
|
749
|
-
raise ValidationError(
|
|
750
|
-
"Ord operation is only for Set and Alias objects!"
|
|
751
|
-
)
|
|
707
|
+
raise ValidationError("Ord operation is only for Set and Alias objects!")
|
|
752
708
|
|
|
753
709
|
if symbol.is_singleton:
|
|
754
710
|
return 1
|
|
@@ -110,9 +110,7 @@ def _cast_values(
|
|
|
110
110
|
num_variables: str,
|
|
111
111
|
solver_time: str,
|
|
112
112
|
) -> tuple[float, int | float, int | float, float]:
|
|
113
|
-
objective = (
|
|
114
|
-
float("nan") if objective_value == "NA" else float(objective_value)
|
|
115
|
-
)
|
|
113
|
+
objective = float("nan") if objective_value == "NA" else float(objective_value)
|
|
116
114
|
equations = float("nan") if num_equations == "NA" else int(num_equations)
|
|
117
115
|
variables = float("nan") if num_variables == "NA" else int(num_variables)
|
|
118
116
|
time = float("nan") if solver_time == "NA" else float(solver_time)
|
|
@@ -193,9 +191,7 @@ class Backend(ABC):
|
|
|
193
191
|
gdx_in = os.path.basename(gdx_in)
|
|
194
192
|
elif self.backend_type == "neos":
|
|
195
193
|
gdx_in = "in.gdx"
|
|
196
|
-
gams_string = self.container._generate_gams_string(
|
|
197
|
-
gdx_in, modified_names
|
|
198
|
-
)
|
|
194
|
+
gams_string = self.container._generate_gams_string(gdx_in, modified_names)
|
|
199
195
|
self.make_unmodified(modified_names)
|
|
200
196
|
|
|
201
197
|
return gams_string
|
|
@@ -225,9 +221,7 @@ class Backend(ABC):
|
|
|
225
221
|
symbols = filtered_names
|
|
226
222
|
|
|
227
223
|
if len(symbols) != 0:
|
|
228
|
-
self.container._load_records_from_gdx(
|
|
229
|
-
self.container._gdx_out, symbols
|
|
230
|
-
)
|
|
224
|
+
self.container._load_records_from_gdx(self.container._gdx_out, symbols)
|
|
231
225
|
self.make_unmodified(symbols)
|
|
232
226
|
|
|
233
227
|
if relaxed_domain_mapping:
|
|
@@ -237,11 +231,7 @@ class Backend(ABC):
|
|
|
237
231
|
|
|
238
232
|
new_domain = []
|
|
239
233
|
for elem in symbol.domain:
|
|
240
|
-
if (
|
|
241
|
-
type(elem) is str
|
|
242
|
-
and elem != "*"
|
|
243
|
-
and elem in self.container
|
|
244
|
-
):
|
|
234
|
+
if type(elem) is str and elem != "*" and elem in self.container:
|
|
245
235
|
new_domain.append(self.container[elem])
|
|
246
236
|
else:
|
|
247
237
|
new_domain.append(elem)
|
|
@@ -293,10 +283,8 @@ class Backend(ABC):
|
|
|
293
283
|
_,
|
|
294
284
|
) = line.split(",")
|
|
295
285
|
|
|
296
|
-
objective_value, num_equations, num_variables, solver_time = (
|
|
297
|
-
|
|
298
|
-
objective_value, num_equations, num_variables, solver_time
|
|
299
|
-
)
|
|
286
|
+
objective_value, num_equations, num_variables, solver_time = _cast_values(
|
|
287
|
+
objective_value, num_equations, num_variables, solver_time
|
|
300
288
|
)
|
|
301
289
|
|
|
302
290
|
dataframe = pd.DataFrame(
|