gamspy 1.15.1.post1__tar.gz → 1.17.0__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.15.1.post1 → gamspy-1.17.0}/PKG-INFO +12 -12
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/README.md +1 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/README_PYPI.md +1 -1
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/pyproject.toml +25 -34
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/condition.py +38 -10
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/domain.py +2 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/expression.py +9 -30
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/operable.py +20 -24
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/operation.py +18 -57
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/backend.py +6 -18
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/engine.py +102 -145
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/neos.py +8 -23
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/cli.py +4 -4
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/gdx.py +142 -41
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/install.py +87 -59
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/list.py +9 -13
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/probe.py +10 -8
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/retrieve.py +11 -15
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/run.py +37 -42
- gamspy-1.17.0/src/gamspy/_cli/show.py +252 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/uninstall.py +46 -24
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/util.py +3 -7
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_config.py +2 -4
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_container.py +41 -49
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_convert.py +16 -43
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_database.py +2 -6
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_extrinsic.py +4 -12
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_miro.py +13 -33
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_model.py +22 -46
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_model_instance.py +18 -53
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_options.py +109 -114
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_serialization.py +1 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/alias.py +4 -9
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/equation.py +34 -31
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_equation.py +3 -5
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_parameter.py +9 -12
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_set.py +3 -9
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_symbol.py +7 -13
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_variable.py +4 -8
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/parameter.py +9 -32
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/set.py +14 -47
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/symbol.py +19 -19
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/universe_alias.py +6 -17
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/variable.py +12 -37
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_types.py +2 -4
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_validation.py +15 -44
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_workspace.py +2 -7
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/exceptions.py +1 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/__init__.py +12 -10
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/decision_tree_struct.py +5 -17
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/gradient_boosting.py +36 -19
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/random_forest.py +34 -15
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/regression_tree.py +58 -78
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/avgpool2d.py +6 -18
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/conv1d.py +12 -39
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/conv2d.py +17 -39
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/linear.py +7 -23
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/maxpool2d.py +1 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/minpool2d.py +1 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/mpool2d.py +9 -23
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/torch_sequential.py +13 -39
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/piecewise.py +18 -45
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/shape.py +2 -6
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/utils.py +6 -19
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/activation.py +11 -16
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/matrix.py +11 -22
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/misc.py +3 -9
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/utils.py +13 -57
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/PKG-INFO +12 -12
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/requires.txt +8 -8
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/tests/test_gamspy.py +4 -24
- gamspy-1.15.1.post1/src/gamspy/_cli/show.py +0 -46
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/LICENSE +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/setup.cfg +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/__main__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/number.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/local.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/__init__.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/__init__.py +2 -2
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/__init__.py +3 -3
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/__init__.py +66 -66
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/log_power.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/probability.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/trigonometric.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/py.typed +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/version.py +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/SOURCES.txt +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/dependency_links.txt +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/entry_points.txt +0 -0
- {gamspy-1.15.1.post1 → gamspy-1.17.0}/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.0
|
|
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/
|
|
@@ -19,29 +19,28 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
19
19
|
Classifier: Programming Language :: Python
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
21
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
23
22
|
Classifier: Programming Language :: Python :: 3.10
|
|
24
23
|
Classifier: Programming Language :: Python :: 3.11
|
|
25
24
|
Classifier: Programming Language :: Python :: 3.12
|
|
26
25
|
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
27
|
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[transfer]<
|
|
35
|
-
Requires-Dist: gamspy_base<
|
|
34
|
+
Requires-Dist: gamsapi[transfer]<52.0.0,>=51.1.0
|
|
35
|
+
Requires-Dist: gamspy_base<52.0.0,>=51.1.0
|
|
36
36
|
Requires-Dist: pydantic>=2.0
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist: typer>=0.15.1
|
|
40
|
-
Requires-Dist: click<8.2.0
|
|
37
|
+
Requires-Dist: requests>=2.28.0
|
|
38
|
+
Requires-Dist: typer>=0.16.0
|
|
41
39
|
Provides-Extra: dev
|
|
42
|
-
Requires-Dist: ruff
|
|
40
|
+
Requires-Dist: ruff>=0.13.0; extra == "dev"
|
|
43
41
|
Requires-Dist: pre-commit>=3.5.0; extra == "dev"
|
|
44
|
-
Requires-Dist: mypy>=1.
|
|
42
|
+
Requires-Dist: mypy>=1.18.1; extra == "dev"
|
|
43
|
+
Requires-Dist: griffe>=1.14.0; extra == "dev"
|
|
45
44
|
Provides-Extra: test
|
|
46
45
|
Requires-Dist: coverage[toml]>=7.2.7; extra == "test"
|
|
47
46
|
Requires-Dist: openpyxl>=3.1.2; extra == "test"
|
|
@@ -67,6 +66,7 @@ Requires-Dist: nbmake>=1.5.3; extra == "doc"
|
|
|
67
66
|
Requires-Dist: openpyxl>=3.1.2; extra == "doc"
|
|
68
67
|
Requires-Dist: sphinx-tabs>=3.4.7; extra == "doc"
|
|
69
68
|
Requires-Dist: towncrier>=24.8.0; extra == "doc"
|
|
69
|
+
Requires-Dist: geopandas>=1.1.1; extra == "doc"
|
|
70
70
|
Provides-Extra: torch
|
|
71
71
|
Requires-Dist: torch>=2.7.0; extra == "torch"
|
|
72
72
|
Dynamic: license-file
|
|
@@ -117,4 +117,4 @@ Here are just a few of the things that **gamspy** does well:
|
|
|
117
117
|
## Getting Help
|
|
118
118
|
|
|
119
119
|
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
|
|
120
|
+
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.0"
|
|
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 = [
|
|
@@ -25,24 +25,22 @@ classifiers = [
|
|
|
25
25
|
"Programming Language :: Python",
|
|
26
26
|
"Programming Language :: Python :: 3",
|
|
27
27
|
"Programming Language :: Python :: 3 :: Only",
|
|
28
|
-
"Programming Language :: Python :: 3.9",
|
|
29
28
|
"Programming Language :: Python :: 3.10",
|
|
30
29
|
"Programming Language :: Python :: 3.11",
|
|
31
30
|
"Programming Language :: Python :: 3.12",
|
|
32
31
|
"Programming Language :: Python :: 3.13",
|
|
32
|
+
"Programming Language :: Python :: 3.14",
|
|
33
33
|
"Operating System :: POSIX",
|
|
34
34
|
"Operating System :: Unix",
|
|
35
35
|
"Operating System :: MacOS",
|
|
36
36
|
"Operating System :: Microsoft :: Windows",
|
|
37
37
|
]
|
|
38
38
|
dependencies = [
|
|
39
|
-
"gamsapi[transfer] >=
|
|
40
|
-
"gamspy_base >=
|
|
39
|
+
"gamsapi[transfer] >= 51.1.0, < 52.0.0",
|
|
40
|
+
"gamspy_base >= 51.1.0, < 52.0.0",
|
|
41
41
|
"pydantic >= 2.0",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"typer >= 0.15.1",
|
|
45
|
-
"click < 8.2.0",
|
|
42
|
+
"requests >= 2.28.0",
|
|
43
|
+
"typer >= 0.16.0",
|
|
46
44
|
]
|
|
47
45
|
|
|
48
46
|
[project.urls]
|
|
@@ -54,9 +52,10 @@ changelog = "https://github.com/GAMS-dev/gamspy/blob/develop/CHANGELOG.md"
|
|
|
54
52
|
|
|
55
53
|
[project.optional-dependencies]
|
|
56
54
|
dev = [
|
|
57
|
-
"ruff
|
|
55
|
+
"ruff >= 0.13.0",
|
|
58
56
|
"pre-commit >= 3.5.0",
|
|
59
|
-
"mypy >= 1.
|
|
57
|
+
"mypy >= 1.18.1",
|
|
58
|
+
"griffe >= 1.14.0",
|
|
60
59
|
]
|
|
61
60
|
|
|
62
61
|
test = [
|
|
@@ -86,6 +85,7 @@ doc = [
|
|
|
86
85
|
"openpyxl>=3.1.2",
|
|
87
86
|
"sphinx-tabs>=3.4.7",
|
|
88
87
|
"towncrier>= 24.8.0",
|
|
88
|
+
"geopandas >= 1.1.1",
|
|
89
89
|
]
|
|
90
90
|
|
|
91
91
|
torch = [
|
|
@@ -211,37 +211,28 @@ exclude = [
|
|
|
211
211
|
"node_modules",
|
|
212
212
|
"site-packages",
|
|
213
213
|
"venv",
|
|
214
|
-
"_cli",
|
|
215
|
-
"_options.py"
|
|
216
214
|
]
|
|
217
215
|
|
|
218
|
-
# Same as
|
|
219
|
-
line-length =
|
|
216
|
+
# Same as black.
|
|
217
|
+
line-length = 88
|
|
220
218
|
indent-width = 4
|
|
221
219
|
|
|
222
|
-
# Assume Python
|
|
223
|
-
target-version = "
|
|
220
|
+
# Assume Python 3.10
|
|
221
|
+
target-version = "py310"
|
|
224
222
|
|
|
225
223
|
[tool.ruff.lint]
|
|
226
224
|
select = [
|
|
227
|
-
# pycodestyle
|
|
228
|
-
"
|
|
229
|
-
#
|
|
230
|
-
"
|
|
231
|
-
#
|
|
232
|
-
"
|
|
233
|
-
# flake8-
|
|
234
|
-
"
|
|
235
|
-
#
|
|
236
|
-
"SIM",
|
|
237
|
-
# isort
|
|
238
|
-
"I",
|
|
239
|
-
# flake8-pie
|
|
240
|
-
"PIE",
|
|
241
|
-
# Consider merging multiple comparisons
|
|
242
|
-
"PLR1714",
|
|
225
|
+
"E", # pycodestyle
|
|
226
|
+
"F", # Pyflakes
|
|
227
|
+
"UP", # pyupgrade
|
|
228
|
+
"B", # flake8-bugbear
|
|
229
|
+
"SIM", # flake8-simplify
|
|
230
|
+
"I", # isort
|
|
231
|
+
"PIE", # flake8-pie
|
|
232
|
+
"PLR1714", # Consider merging multiple comparisons
|
|
233
|
+
"RUF", # Ruff-specific rules
|
|
243
234
|
]
|
|
244
|
-
ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006"]
|
|
235
|
+
ignore = ["E203", "E501", "E701", "E741", "E743", "W605", "SIM105", "SIM115", "B028", "B006", "RUF005", "RUF022"]
|
|
245
236
|
|
|
246
237
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
247
238
|
fixable = ["ALL"]
|
|
@@ -2,12 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from typing import TYPE_CHECKING
|
|
4
4
|
|
|
5
|
+
import gamspy._algebra.domain as domain
|
|
5
6
|
import gamspy._algebra.expression as expression
|
|
6
7
|
import gamspy._algebra.operable as operable
|
|
7
8
|
import gamspy._symbols as syms
|
|
8
9
|
import gamspy._symbols.implicits as implicits
|
|
9
10
|
import gamspy.utils as utils
|
|
10
11
|
from gamspy._symbols.implicits.implicit_symbol import ImplicitSymbol
|
|
12
|
+
from gamspy._symbols.symbol import Symbol
|
|
11
13
|
|
|
12
14
|
if TYPE_CHECKING:
|
|
13
15
|
import pandas as pd
|
|
@@ -94,15 +96,16 @@ class Condition(operable.Operable):
|
|
|
94
96
|
statement = expression.Expression(lhs, op_type, rhs)
|
|
95
97
|
|
|
96
98
|
if isinstance(self.conditioning_on, ImplicitSymbol):
|
|
97
|
-
statement._validate_definition(
|
|
98
|
-
utils._unpack(self.conditioning_on.domain)
|
|
99
|
-
)
|
|
99
|
+
statement._validate_definition(utils._unpack(self.conditioning_on.domain))
|
|
100
100
|
|
|
101
101
|
self.conditioning_on.container._add_statement(statement)
|
|
102
102
|
|
|
103
103
|
if isinstance(self.conditioning_on, ImplicitSymbol):
|
|
104
104
|
self.conditioning_on.parent._assignment = statement
|
|
105
105
|
self.conditioning_on.parent._winner = "gams"
|
|
106
|
+
elif isinstance(self.conditioning_on, Symbol):
|
|
107
|
+
self.conditioning_on._assignment = statement
|
|
108
|
+
self.conditioning_on._winner = "gams"
|
|
106
109
|
|
|
107
110
|
if isinstance(self.conditioning_on, implicits.ImplicitEquation):
|
|
108
111
|
self.conditioning_on.parent._definition = statement
|
|
@@ -123,13 +126,38 @@ class Condition(operable.Operable):
|
|
|
123
126
|
def records(self) -> pd.DataFrame | None:
|
|
124
127
|
assert self.container is not None
|
|
125
128
|
assert self.domain is not None
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if isinstance(
|
|
130
|
+
self.conditioning_on,
|
|
131
|
+
(syms.Set, syms.Alias, implicits.ImplicitSet),
|
|
132
|
+
):
|
|
133
|
+
temp_name = "c" + utils._get_unique_name()
|
|
134
|
+
temp_sym = syms.Set._constructor_bypass(
|
|
135
|
+
self.container,
|
|
136
|
+
temp_name,
|
|
137
|
+
self.domain, # type: ignore
|
|
138
|
+
)
|
|
139
|
+
temp_sym[...] = self
|
|
140
|
+
del self.container.data[temp_name]
|
|
141
|
+
elif isinstance(self.conditioning_on, domain.Domain):
|
|
142
|
+
temp_name = "c" + utils._get_unique_name()
|
|
143
|
+
temp_sym = syms.Set._constructor_bypass(
|
|
144
|
+
self.container,
|
|
145
|
+
temp_name,
|
|
146
|
+
self.domain, # type: ignore
|
|
147
|
+
)
|
|
148
|
+
temp_sym[...].where[self.condition] = True
|
|
149
|
+
del self.container.data[temp_name]
|
|
150
|
+
else:
|
|
151
|
+
temp_name = "c" + utils._get_unique_name()
|
|
152
|
+
temp_sym = syms.Parameter._constructor_bypass(
|
|
153
|
+
self.container,
|
|
154
|
+
temp_name,
|
|
155
|
+
self.domain, # type: ignore
|
|
156
|
+
)
|
|
157
|
+
temp_sym[...] = self
|
|
158
|
+
del self.container.data[temp_name]
|
|
159
|
+
|
|
160
|
+
return temp_sym.records
|
|
133
161
|
|
|
134
162
|
def gamsRepr(self) -> str:
|
|
135
163
|
condition_str = (
|
|
@@ -39,6 +39,7 @@ class Domain:
|
|
|
39
39
|
self._sanity_check(sets)
|
|
40
40
|
self.sets = sets
|
|
41
41
|
self.container = self._find_container() # type: ignore
|
|
42
|
+
self.domain = sets
|
|
42
43
|
self.where = condition.Condition(self)
|
|
43
44
|
|
|
44
45
|
def __repr__(self) -> str:
|
|
@@ -46,9 +47,7 @@ class Domain:
|
|
|
46
47
|
|
|
47
48
|
def _sanity_check(self, sets: tuple[Set | Alias | ImplicitSet, ...]):
|
|
48
49
|
if len(sets) < 2:
|
|
49
|
-
error_message = (
|
|
50
|
-
f"Domain requires at least 2 sets but found {len(sets)}. "
|
|
51
|
-
)
|
|
50
|
+
error_message = f"Domain requires at least 2 sets but found {len(sets)}. "
|
|
52
51
|
if len(sets) == 1:
|
|
53
52
|
error_message += f"You can directly limit the domain with {sets[0].name}.where[<your_limitation>]."
|
|
54
53
|
raise ValidationError(error_message)
|
|
@@ -181,14 +181,10 @@ def create_gams_expression(root_node: Expression) -> str:
|
|
|
181
181
|
right_str, right_prec = eval_stack.pop()
|
|
182
182
|
left_str, left_prec = eval_stack.pop()
|
|
183
183
|
|
|
184
|
-
if left_prec < op_prec or (
|
|
185
|
-
left_prec == op_prec and op_assoc == "right"
|
|
186
|
-
):
|
|
184
|
+
if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
|
|
187
185
|
left_str = f"({left_str})"
|
|
188
186
|
|
|
189
|
-
if right_prec < op_prec or (
|
|
190
|
-
right_prec == op_prec and op_assoc == "left"
|
|
191
|
-
):
|
|
187
|
+
if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
|
|
192
188
|
right_str = f"({right_str})"
|
|
193
189
|
|
|
194
190
|
# get around 80000 line length limitation in GAMS
|
|
@@ -272,20 +268,14 @@ def create_latex_expression(root_node: Expression) -> str:
|
|
|
272
268
|
right_str, right_prec = eval_stack.pop()
|
|
273
269
|
left_str, left_prec = eval_stack.pop()
|
|
274
270
|
|
|
275
|
-
if left_prec < op_prec or (
|
|
276
|
-
left_prec == op_prec and op_assoc == "right"
|
|
277
|
-
):
|
|
271
|
+
if left_prec < op_prec or (left_prec == op_prec and op_assoc == "right"):
|
|
278
272
|
left_str = f"({left_str})"
|
|
279
273
|
|
|
280
|
-
if right_prec < op_prec or (
|
|
281
|
-
right_prec == op_prec and op_assoc == "left"
|
|
282
|
-
):
|
|
274
|
+
if right_prec < op_prec or (right_prec == op_prec and op_assoc == "left"):
|
|
283
275
|
right_str = f"({right_str})"
|
|
284
276
|
|
|
285
277
|
if op == "/":
|
|
286
|
-
eval_stack.append(
|
|
287
|
-
(f"\\frac{{{left_str}}}{{{right_str}}}", op_prec)
|
|
288
|
-
)
|
|
278
|
+
eval_stack.append((f"\\frac{{{left_str}}}{{{right_str}}}", op_prec))
|
|
289
279
|
continue
|
|
290
280
|
|
|
291
281
|
op = op_map.get(op, op)
|
|
@@ -334,16 +324,10 @@ class Expression(operable.Operable):
|
|
|
334
324
|
operator: str,
|
|
335
325
|
right: OperableType | str | None,
|
|
336
326
|
):
|
|
337
|
-
self.left = (
|
|
338
|
-
utils._map_special_values(left)
|
|
339
|
-
if isinstance(left, float)
|
|
340
|
-
else left
|
|
341
|
-
)
|
|
327
|
+
self.left = utils._map_special_values(left) if isinstance(left, float) else left
|
|
342
328
|
self.operator = operator
|
|
343
329
|
self.right = (
|
|
344
|
-
utils._map_special_values(right)
|
|
345
|
-
if isinstance(right, float)
|
|
346
|
-
else right
|
|
330
|
+
utils._map_special_values(right) if isinstance(right, float) else right
|
|
347
331
|
)
|
|
348
332
|
|
|
349
333
|
if operator == "=" and isinstance(right, Expression):
|
|
@@ -725,9 +709,7 @@ class Expression(operable.Operable):
|
|
|
725
709
|
def _validate_definition(
|
|
726
710
|
self, control_stack: list[Set | Alias | ImplicitSet]
|
|
727
711
|
) -> None:
|
|
728
|
-
if not get_option("DOMAIN_VALIDATION") or not get_option(
|
|
729
|
-
"DOMAIN_VALIDATION"
|
|
730
|
-
):
|
|
712
|
+
if not get_option("DOMAIN_VALIDATION") or not get_option("DOMAIN_VALIDATION"):
|
|
731
713
|
return
|
|
732
714
|
|
|
733
715
|
stack = []
|
|
@@ -747,10 +729,7 @@ class Expression(operable.Operable):
|
|
|
747
729
|
if hasattr(elem, "is_singleton") and elem.is_singleton:
|
|
748
730
|
continue
|
|
749
731
|
|
|
750
|
-
if (
|
|
751
|
-
isinstance(elem, Symbol)
|
|
752
|
-
and elem not in control_stack
|
|
753
|
-
):
|
|
732
|
+
if isinstance(elem, Symbol) and elem not in control_stack:
|
|
754
733
|
raise ValidationError(
|
|
755
734
|
f"Uncontrolled set `{elem}` entered as constant!"
|
|
756
735
|
)
|
|
@@ -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"""
|
|
@@ -31,12 +31,7 @@ if TYPE_CHECKING:
|
|
|
31
31
|
class Operation(operable.Operable):
|
|
32
32
|
def __init__(
|
|
33
33
|
self,
|
|
34
|
-
domain: Set
|
|
35
|
-
| Alias
|
|
36
|
-
| ImplicitSet
|
|
37
|
-
| Sequence[Set | Alias]
|
|
38
|
-
| Domain
|
|
39
|
-
| Condition,
|
|
34
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
40
35
|
rhs: (
|
|
41
36
|
Expression
|
|
42
37
|
| Operation
|
|
@@ -160,9 +155,7 @@ class Operation(operable.Operable):
|
|
|
160
155
|
for elem in self.raw_domain:
|
|
161
156
|
if isinstance(elem, implicits.ImplicitSet):
|
|
162
157
|
control_stack += [
|
|
163
|
-
member
|
|
164
|
-
for member in elem.domain
|
|
165
|
-
if member not in control_stack
|
|
158
|
+
member for member in elem.domain if member not in control_stack
|
|
166
159
|
] + [elem.parent]
|
|
167
160
|
|
|
168
161
|
if elem in control_stack:
|
|
@@ -178,11 +171,7 @@ class Operation(operable.Operable):
|
|
|
178
171
|
if len(self.op_domain) == 1:
|
|
179
172
|
return self.op_domain[0].gamsRepr()
|
|
180
173
|
|
|
181
|
-
return (
|
|
182
|
-
"("
|
|
183
|
-
+ ",".join([index.gamsRepr() for index in self.op_domain])
|
|
184
|
-
+ ")"
|
|
185
|
-
)
|
|
174
|
+
return "(" + ",".join([index.gamsRepr() for index in self.op_domain]) + ")"
|
|
186
175
|
|
|
187
176
|
def __eq__(self, other):
|
|
188
177
|
return expression.Expression(self, "=e=", other)
|
|
@@ -266,9 +255,7 @@ class Operation(operable.Operable):
|
|
|
266
255
|
if isinstance(self.rhs, (int, float, str))
|
|
267
256
|
else self.rhs.latexRepr()
|
|
268
257
|
)
|
|
269
|
-
representation =
|
|
270
|
-
f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
|
|
271
|
-
)
|
|
258
|
+
representation = f"\\{op_map[self._op_name]}_{{{index_str}}} {expression_str}"
|
|
272
259
|
return representation
|
|
273
260
|
|
|
274
261
|
|
|
@@ -305,12 +292,7 @@ class Sum(Operation):
|
|
|
305
292
|
|
|
306
293
|
def __init__(
|
|
307
294
|
self,
|
|
308
|
-
domain: Set
|
|
309
|
-
| Alias
|
|
310
|
-
| ImplicitSet
|
|
311
|
-
| Sequence[Set | Alias]
|
|
312
|
-
| Domain
|
|
313
|
-
| Condition,
|
|
295
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
314
296
|
expression: Operation
|
|
315
297
|
| Expression
|
|
316
298
|
| MathOp
|
|
@@ -381,12 +363,7 @@ class Product(Operation):
|
|
|
381
363
|
|
|
382
364
|
def __init__(
|
|
383
365
|
self,
|
|
384
|
-
domain: Set
|
|
385
|
-
| Alias
|
|
386
|
-
| ImplicitSet
|
|
387
|
-
| Sequence[Set | Alias]
|
|
388
|
-
| Domain
|
|
389
|
-
| Condition,
|
|
366
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
390
367
|
expression: Operation
|
|
391
368
|
| Expression
|
|
392
369
|
| MathOp
|
|
@@ -457,12 +434,7 @@ class Smin(Operation):
|
|
|
457
434
|
|
|
458
435
|
def __init__(
|
|
459
436
|
self,
|
|
460
|
-
domain: Set
|
|
461
|
-
| Alias
|
|
462
|
-
| ImplicitSet
|
|
463
|
-
| Sequence[Set | Alias]
|
|
464
|
-
| Domain
|
|
465
|
-
| Condition,
|
|
437
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
466
438
|
expression: Operation
|
|
467
439
|
| Expression
|
|
468
440
|
| MathOp
|
|
@@ -533,12 +505,7 @@ class Smax(Operation):
|
|
|
533
505
|
|
|
534
506
|
def __init__(
|
|
535
507
|
self,
|
|
536
|
-
domain: Set
|
|
537
|
-
| Alias
|
|
538
|
-
| ImplicitSet
|
|
539
|
-
| Sequence[Set | Alias]
|
|
540
|
-
| Domain
|
|
541
|
-
| Condition,
|
|
508
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
542
509
|
expression: Operation
|
|
543
510
|
| Expression
|
|
544
511
|
| MathOp
|
|
@@ -609,12 +576,7 @@ class Sand(Operation):
|
|
|
609
576
|
|
|
610
577
|
def __init__(
|
|
611
578
|
self,
|
|
612
|
-
domain: Set
|
|
613
|
-
| Alias
|
|
614
|
-
| ImplicitSet
|
|
615
|
-
| Sequence[Set | Alias]
|
|
616
|
-
| Domain
|
|
617
|
-
| Condition,
|
|
579
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
618
580
|
expression: Operation
|
|
619
581
|
| Expression
|
|
620
582
|
| MathOp
|
|
@@ -684,12 +646,7 @@ class Sor(Operation):
|
|
|
684
646
|
|
|
685
647
|
def __init__(
|
|
686
648
|
self,
|
|
687
|
-
domain: Set
|
|
688
|
-
| Alias
|
|
689
|
-
| ImplicitSet
|
|
690
|
-
| Sequence[Set | Alias]
|
|
691
|
-
| Domain
|
|
692
|
-
| Condition,
|
|
649
|
+
domain: Set | Alias | ImplicitSet | Sequence[Set | Alias] | Domain | Condition,
|
|
693
650
|
expression: Operation
|
|
694
651
|
| Expression
|
|
695
652
|
| MathOp
|
|
@@ -744,12 +701,16 @@ class Ord(operable.Operable):
|
|
|
744
701
|
|
|
745
702
|
"""
|
|
746
703
|
|
|
747
|
-
def
|
|
704
|
+
def __new__(cls, symbol: Set | Alias):
|
|
748
705
|
if not isinstance(symbol, (syms.Set, syms.Alias)):
|
|
749
|
-
raise ValidationError(
|
|
750
|
-
"Ord operation is only for Set and Alias objects!"
|
|
751
|
-
)
|
|
706
|
+
raise ValidationError("Ord operation is only for Set and Alias objects!")
|
|
752
707
|
|
|
708
|
+
if symbol.is_singleton:
|
|
709
|
+
return 1
|
|
710
|
+
|
|
711
|
+
return super().__new__(cls)
|
|
712
|
+
|
|
713
|
+
def __init__(self, symbol: Set | Alias):
|
|
753
714
|
self._symbol = symbol
|
|
754
715
|
self.container = symbol.container
|
|
755
716
|
self.domain: list[Set | Alias] = []
|
|
@@ -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(
|