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.
Files changed (95) hide show
  1. {gamspy-1.15.1.post1 → gamspy-1.17.0}/PKG-INFO +12 -12
  2. {gamspy-1.15.1.post1 → gamspy-1.17.0}/README.md +1 -0
  3. {gamspy-1.15.1.post1 → gamspy-1.17.0}/README_PYPI.md +1 -1
  4. {gamspy-1.15.1.post1 → gamspy-1.17.0}/pyproject.toml +25 -34
  5. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/condition.py +38 -10
  6. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/domain.py +2 -3
  7. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/expression.py +9 -30
  8. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/operable.py +20 -24
  9. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/operation.py +18 -57
  10. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/backend.py +6 -18
  11. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/engine.py +102 -145
  12. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/neos.py +8 -23
  13. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/cli.py +4 -4
  14. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/gdx.py +142 -41
  15. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/install.py +87 -59
  16. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/list.py +9 -13
  17. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/probe.py +10 -8
  18. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/retrieve.py +11 -15
  19. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/run.py +37 -42
  20. gamspy-1.17.0/src/gamspy/_cli/show.py +252 -0
  21. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/uninstall.py +46 -24
  22. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/util.py +3 -7
  23. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_config.py +2 -4
  24. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_container.py +41 -49
  25. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_convert.py +16 -43
  26. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_database.py +2 -6
  27. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_extrinsic.py +4 -12
  28. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_miro.py +13 -33
  29. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_model.py +22 -46
  30. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_model_instance.py +18 -53
  31. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_options.py +109 -114
  32. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_serialization.py +1 -3
  33. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/alias.py +4 -9
  34. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/equation.py +34 -31
  35. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_equation.py +3 -5
  36. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_parameter.py +9 -12
  37. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_set.py +3 -9
  38. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_symbol.py +7 -13
  39. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/implicit_variable.py +4 -8
  40. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/parameter.py +9 -32
  41. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/set.py +14 -47
  42. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/symbol.py +19 -19
  43. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/universe_alias.py +6 -17
  44. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/variable.py +12 -37
  45. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_types.py +2 -4
  46. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_validation.py +15 -44
  47. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_workspace.py +2 -7
  48. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/exceptions.py +1 -3
  49. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/__init__.py +12 -10
  50. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/decision_tree_struct.py +5 -17
  51. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/gradient_boosting.py +36 -19
  52. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/random_forest.py +34 -15
  53. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/regression_tree.py +58 -78
  54. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/avgpool2d.py +6 -18
  55. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/conv1d.py +12 -39
  56. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/conv2d.py +17 -39
  57. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/linear.py +7 -23
  58. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/maxpool2d.py +1 -3
  59. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/minpool2d.py +1 -3
  60. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/mpool2d.py +9 -23
  61. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/torch_sequential.py +13 -39
  62. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/piecewise.py +18 -45
  63. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/shape.py +2 -6
  64. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/utils.py +6 -19
  65. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/activation.py +11 -16
  66. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/matrix.py +11 -22
  67. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/misc.py +3 -9
  68. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/utils.py +13 -57
  69. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/PKG-INFO +12 -12
  70. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/requires.txt +8 -8
  71. {gamspy-1.15.1.post1 → gamspy-1.17.0}/tests/test_gamspy.py +4 -24
  72. gamspy-1.15.1.post1/src/gamspy/_cli/show.py +0 -46
  73. {gamspy-1.15.1.post1 → gamspy-1.17.0}/LICENSE +0 -0
  74. {gamspy-1.15.1.post1 → gamspy-1.17.0}/setup.cfg +0 -0
  75. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/__init__.py +0 -0
  76. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/__main__.py +0 -0
  77. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/__init__.py +0 -0
  78. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_algebra/number.py +0 -0
  79. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/__init__.py +0 -0
  80. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_backend/local.py +0 -0
  81. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_cli/__init__.py +0 -0
  82. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/__init__.py +0 -0
  83. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/_symbols/implicits/__init__.py +0 -0
  84. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/ml/__init__.py +2 -2
  85. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/formulations/nn/__init__.py +3 -3
  86. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/__init__.py +66 -66
  87. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/log_power.py +0 -0
  88. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/probability.py +0 -0
  89. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/math/trigonometric.py +0 -0
  90. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/py.typed +0 -0
  91. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy/version.py +0 -0
  92. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/SOURCES.txt +0 -0
  93. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/dependency_links.txt +0 -0
  94. {gamspy-1.15.1.post1 → gamspy-1.17.0}/src/gamspy.egg-info/entry_points.txt +0 -0
  95. {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.15.1.post1
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.9
31
+ Requires-Python: >=3.10
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
- Requires-Dist: gamsapi[transfer]<51.0.0,>=50.5.0
35
- Requires-Dist: gamspy_base<51.0.0,>=50.5.0
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: certifi>=2022.09.14
38
- Requires-Dist: urllib3>=2.0.7
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==0.12.0; extra == "dev"
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.11.1; extra == "dev"
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/c/gamspy-help).
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
  [![PyPI version](https://img.shields.io/pypi/v/gamspy.svg?maxAge=3600)](https://gamspy.readthedocs.io/en/latest/)
5
5
  [![Downloads](https://static.pepy.tech/badge/gamspy)](https://pepy.tech/project/gamspy)
6
+ [![Supported versions](https://img.shields.io/pypi/pyversions/gamspy.svg)](https://pypi.python.org/pypi/gamspy)
6
7
  [![Documentation Status](https://readthedocs.org/projects/gamspy/badge/?version=latest)](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/c/gamspy-help).
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.15.1.post1"
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.9"
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] >= 50.5.0, < 51.0.0",
40
- "gamspy_base >= 50.5.0, < 51.0.0",
39
+ "gamsapi[transfer] >= 51.1.0, < 52.0.0",
40
+ "gamspy_base >= 51.1.0, < 52.0.0",
41
41
  "pydantic >= 2.0",
42
- "certifi >= 2022.09.14",
43
- "urllib3 >= 2.0.7",
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 == 0.12.0",
55
+ "ruff >= 0.13.0",
58
56
  "pre-commit >= 3.5.0",
59
- "mypy >= 1.11.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 PEP8.
219
- line-length = 79
216
+ # Same as black.
217
+ line-length = 88
220
218
  indent-width = 4
221
219
 
222
- # Assume Python 9
223
- target-version = "py39"
220
+ # Assume Python 3.10
221
+ target-version = "py310"
224
222
 
225
223
  [tool.ruff.lint]
226
224
  select = [
227
- # pycodestyle
228
- "E",
229
- # Pyflakes
230
- "F",
231
- # pyupgrade
232
- "UP",
233
- # flake8-bugbear
234
- "B",
235
- # flake8-simplify
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
- temp_name = "a" + utils._get_unique_name()
127
- temp_param = syms.Parameter._constructor_bypass(
128
- self.container, temp_name, self.domain
129
- )
130
- temp_param[...] = self
131
- del self.container.data[temp_name]
132
- return temp_param.records
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
- self, (ImplicitSet, expression.SetExpression)
37
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, (ImplicitSet, expression.SetExpression)
47
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, (ImplicitSet, expression.SetExpression)
63
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, (ImplicitSet, expression.SetExpression)
73
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, (ImplicitSet, expression.SetExpression)
92
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, (ImplicitSet, expression.SetExpression)
102
- ) or isinstance(other, (ImplicitSet, expression.SetExpression)):
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
- self, other
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 __init__(self, symbol: Set | Alias):
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
- _cast_values(
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(