gamsapi 52.5.0__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gams/__init__.py +27 -0
- gams/_version.py +1 -0
- gams/connect/__init__.py +28 -0
- gams/connect/agents/__init__.py +24 -0
- gams/connect/agents/_excel/__init__.py +32 -0
- gams/connect/agents/_excel/excelagent.py +312 -0
- gams/connect/agents/_excel/workbook.py +155 -0
- gams/connect/agents/_sqlconnectors/__init__.py +42 -0
- gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
- gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
- gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
- gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
- gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
- gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
- gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
- gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
- gams/connect/agents/concatenate.py +440 -0
- gams/connect/agents/connectagent.py +743 -0
- gams/connect/agents/csvreader.py +675 -0
- gams/connect/agents/csvwriter.py +151 -0
- gams/connect/agents/domainwriter.py +143 -0
- gams/connect/agents/excelreader.py +756 -0
- gams/connect/agents/excelwriter.py +467 -0
- gams/connect/agents/filter.py +223 -0
- gams/connect/agents/gamsreader.py +112 -0
- gams/connect/agents/gamswriter.py +239 -0
- gams/connect/agents/gdxreader.py +109 -0
- gams/connect/agents/gdxwriter.py +146 -0
- gams/connect/agents/labelmanipulator.py +303 -0
- gams/connect/agents/projection.py +539 -0
- gams/connect/agents/pythoncode.py +71 -0
- gams/connect/agents/rawcsvreader.py +248 -0
- gams/connect/agents/rawexcelreader.py +312 -0
- gams/connect/agents/schema/CSVReader.yaml +92 -0
- gams/connect/agents/schema/CSVWriter.yaml +44 -0
- gams/connect/agents/schema/Concatenate.yaml +52 -0
- gams/connect/agents/schema/DomainWriter.yaml +25 -0
- gams/connect/agents/schema/ExcelReader.yaml +121 -0
- gams/connect/agents/schema/ExcelWriter.yaml +78 -0
- gams/connect/agents/schema/Filter.yaml +74 -0
- gams/connect/agents/schema/GAMSReader.yaml +20 -0
- gams/connect/agents/schema/GAMSWriter.yaml +47 -0
- gams/connect/agents/schema/GDXReader.yaml +23 -0
- gams/connect/agents/schema/GDXWriter.yaml +32 -0
- gams/connect/agents/schema/LabelManipulator.yaml +99 -0
- gams/connect/agents/schema/Projection.yaml +24 -0
- gams/connect/agents/schema/PythonCode.yaml +6 -0
- gams/connect/agents/schema/RawCSVReader.yaml +34 -0
- gams/connect/agents/schema/RawExcelReader.yaml +42 -0
- gams/connect/agents/schema/SQLReader.yaml +75 -0
- gams/connect/agents/schema/SQLWriter.yaml +103 -0
- gams/connect/agents/sqlreader.py +301 -0
- gams/connect/agents/sqlwriter.py +276 -0
- gams/connect/connectdatabase.py +275 -0
- gams/connect/connectvalidator.py +93 -0
- gams/connect/errors.py +34 -0
- gams/control/__init__.py +136 -0
- gams/control/database.py +2231 -0
- gams/control/execution.py +1900 -0
- gams/control/options.py +2792 -0
- gams/control/workspace.py +1198 -0
- gams/core/__init__.py +24 -0
- gams/core/cfg/__init__.py +26 -0
- gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
- gams/core/cfg/cfgmcc.py +519 -0
- gams/core/dct/__init__.py +26 -0
- gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
- gams/core/dct/dctmcc.py +574 -0
- gams/core/embedded/__init__.py +26 -0
- gams/core/embedded/gamsemb.py +1024 -0
- gams/core/emp/__init__.py +24 -0
- gams/core/emp/emplexer.py +89 -0
- gams/core/emp/empyacc.py +281 -0
- gams/core/gdx/__init__.py +26 -0
- gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
- gams/core/gdx/gdxcc.py +866 -0
- gams/core/gev/__init__.py +26 -0
- gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
- gams/core/gev/gevmcc.py +855 -0
- gams/core/gmd/__init__.py +26 -0
- gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmd/gmdcc.py +917 -0
- gams/core/gmo/__init__.py +26 -0
- gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmo/gmomcc.py +2046 -0
- gams/core/idx/__init__.py +26 -0
- gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
- gams/core/idx/idxcc.py +510 -0
- gams/core/numpy/__init__.py +29 -0
- gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
- gams/core/numpy/gams2numpy.py +1048 -0
- gams/core/opt/__init__.py +26 -0
- gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
- gams/core/opt/optcc.py +840 -0
- gams/engine/__init__.py +204 -0
- gams/engine/api/__init__.py +13 -0
- gams/engine/api/auth_api.py +7653 -0
- gams/engine/api/cleanup_api.py +751 -0
- gams/engine/api/default_api.py +887 -0
- gams/engine/api/hypercube_api.py +2629 -0
- gams/engine/api/jobs_api.py +5229 -0
- gams/engine/api/licenses_api.py +2220 -0
- gams/engine/api/namespaces_api.py +7783 -0
- gams/engine/api/usage_api.py +5627 -0
- gams/engine/api/users_api.py +5931 -0
- gams/engine/api_client.py +804 -0
- gams/engine/api_response.py +21 -0
- gams/engine/configuration.py +601 -0
- gams/engine/exceptions.py +216 -0
- gams/engine/models/__init__.py +86 -0
- gams/engine/models/bad_input.py +89 -0
- gams/engine/models/cleanable_job_result.py +104 -0
- gams/engine/models/cleanable_job_result_page.py +113 -0
- gams/engine/models/engine_license.py +107 -0
- gams/engine/models/files_not_found.py +93 -0
- gams/engine/models/forwarded_token_response.py +112 -0
- gams/engine/models/generic_key_value_pair.py +89 -0
- gams/engine/models/hypercube.py +160 -0
- gams/engine/models/hypercube_page.py +111 -0
- gams/engine/models/hypercube_summary.py +91 -0
- gams/engine/models/hypercube_token.py +97 -0
- gams/engine/models/identity_provider.py +107 -0
- gams/engine/models/identity_provider_ldap.py +121 -0
- gams/engine/models/identity_provider_oauth2.py +146 -0
- gams/engine/models/identity_provider_oauth2_scope.py +89 -0
- gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
- gams/engine/models/identity_provider_oidc.py +133 -0
- gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
- gams/engine/models/inex.py +91 -0
- gams/engine/models/invitation.py +136 -0
- gams/engine/models/invitation_quota.py +106 -0
- gams/engine/models/invitation_token.py +87 -0
- gams/engine/models/job.py +165 -0
- gams/engine/models/job_no_text_entry.py +138 -0
- gams/engine/models/job_no_text_entry_page.py +111 -0
- gams/engine/models/license.py +91 -0
- gams/engine/models/log_piece.py +96 -0
- gams/engine/models/message.py +87 -0
- gams/engine/models/message_and_token.py +99 -0
- gams/engine/models/message_with_webhook_id.py +89 -0
- gams/engine/models/model_auth_token.py +87 -0
- gams/engine/models/model_configuration.py +125 -0
- gams/engine/models/model_default_instance.py +99 -0
- gams/engine/models/model_default_user_instance.py +98 -0
- gams/engine/models/model_hypercube_job.py +106 -0
- gams/engine/models/model_hypercube_usage.py +130 -0
- gams/engine/models/model_instance_info.py +116 -0
- gams/engine/models/model_instance_info_full.py +123 -0
- gams/engine/models/model_instance_pool_info.py +112 -0
- gams/engine/models/model_job_labels.py +179 -0
- gams/engine/models/model_job_usage.py +133 -0
- gams/engine/models/model_pool_usage.py +124 -0
- gams/engine/models/model_usage.py +115 -0
- gams/engine/models/model_user.py +96 -0
- gams/engine/models/model_userinstance_info.py +119 -0
- gams/engine/models/model_userinstancepool_info.py +95 -0
- gams/engine/models/model_version.py +91 -0
- gams/engine/models/models.py +120 -0
- gams/engine/models/namespace.py +104 -0
- gams/engine/models/namespace_quota.py +96 -0
- gams/engine/models/namespace_with_permission.py +96 -0
- gams/engine/models/not_found.py +91 -0
- gams/engine/models/password_policy.py +97 -0
- gams/engine/models/perm_and_username.py +89 -0
- gams/engine/models/quota.py +117 -0
- gams/engine/models/quota_exceeded.py +97 -0
- gams/engine/models/status_code_meaning.py +89 -0
- gams/engine/models/stream_entry.py +89 -0
- gams/engine/models/system_wide_license.py +92 -0
- gams/engine/models/text_entries.py +87 -0
- gams/engine/models/text_entry.py +101 -0
- gams/engine/models/time_span.py +95 -0
- gams/engine/models/time_span_pool_worker.py +99 -0
- gams/engine/models/token_forward_error.py +87 -0
- gams/engine/models/user.py +127 -0
- gams/engine/models/user_group_member.py +96 -0
- gams/engine/models/user_groups.py +108 -0
- gams/engine/models/vapid_info.py +87 -0
- gams/engine/models/webhook.py +138 -0
- gams/engine/models/webhook_parameterized_event.py +99 -0
- gams/engine/py.typed +0 -0
- gams/engine/rest.py +258 -0
- gams/magic/__init__.py +32 -0
- gams/magic/gams_magic.py +142 -0
- gams/magic/interactive.py +402 -0
- gams/tools/__init__.py +30 -0
- gams/tools/errors.py +34 -0
- gams/tools/toolcollection/__init__.py +24 -0
- gams/tools/toolcollection/alg/__init__.py +24 -0
- gams/tools/toolcollection/alg/rank.py +51 -0
- gams/tools/toolcollection/data/__init__.py +24 -0
- gams/tools/toolcollection/data/csvread.py +444 -0
- gams/tools/toolcollection/data/csvwrite.py +311 -0
- gams/tools/toolcollection/data/exceldump.py +47 -0
- gams/tools/toolcollection/data/sqlitewrite.py +276 -0
- gams/tools/toolcollection/gdxservice/__init__.py +24 -0
- gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
- gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
- gams/tools/toolcollection/linalg/__init__.py +24 -0
- gams/tools/toolcollection/linalg/cholesky.py +57 -0
- gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
- gams/tools/toolcollection/linalg/eigenvector.py +58 -0
- gams/tools/toolcollection/linalg/invert.py +55 -0
- gams/tools/toolcollection/linalg/ols.py +138 -0
- gams/tools/toolcollection/tooltemplate.py +321 -0
- gams/tools/toolcollection/win32/__init__.py +24 -0
- gams/tools/toolcollection/win32/excelmerge.py +93 -0
- gams/tools/toolcollection/win32/exceltalk.py +76 -0
- gams/tools/toolcollection/win32/msappavail.py +49 -0
- gams/tools/toolcollection/win32/shellexecute.py +54 -0
- gams/tools/tools.py +116 -0
- gams/transfer/__init__.py +35 -0
- gams/transfer/_abcs/__init__.py +37 -0
- gams/transfer/_abcs/container_abcs.py +433 -0
- gams/transfer/_internals/__init__.py +63 -0
- gams/transfer/_internals/algorithms.py +436 -0
- gams/transfer/_internals/casepreservingdict.py +124 -0
- gams/transfer/_internals/constants.py +270 -0
- gams/transfer/_internals/domainviolation.py +103 -0
- gams/transfer/_internals/specialvalues.py +172 -0
- gams/transfer/containers/__init__.py +26 -0
- gams/transfer/containers/_container.py +1794 -0
- gams/transfer/containers/_io/__init__.py +28 -0
- gams/transfer/containers/_io/containers.py +164 -0
- gams/transfer/containers/_io/gdx.py +1029 -0
- gams/transfer/containers/_io/gmd.py +872 -0
- gams/transfer/containers/_mixins/__init__.py +26 -0
- gams/transfer/containers/_mixins/ccc.py +1274 -0
- gams/transfer/syms/__init__.py +33 -0
- gams/transfer/syms/_methods/__init__.py +24 -0
- gams/transfer/syms/_methods/tables.py +120 -0
- gams/transfer/syms/_methods/toDict.py +115 -0
- gams/transfer/syms/_methods/toList.py +83 -0
- gams/transfer/syms/_methods/toValue.py +60 -0
- gams/transfer/syms/_mixins/__init__.py +32 -0
- gams/transfer/syms/_mixins/equals.py +626 -0
- gams/transfer/syms/_mixins/generateRecords.py +499 -0
- gams/transfer/syms/_mixins/pivot.py +313 -0
- gams/transfer/syms/_mixins/pve.py +627 -0
- gams/transfer/syms/_mixins/sa.py +27 -0
- gams/transfer/syms/_mixins/sapve.py +27 -0
- gams/transfer/syms/_mixins/saua.py +27 -0
- gams/transfer/syms/_mixins/sauapve.py +199 -0
- gams/transfer/syms/_mixins/spve.py +1528 -0
- gams/transfer/syms/_mixins/ve.py +936 -0
- gams/transfer/syms/container_syms/__init__.py +31 -0
- gams/transfer/syms/container_syms/_alias.py +984 -0
- gams/transfer/syms/container_syms/_equation.py +333 -0
- gams/transfer/syms/container_syms/_parameter.py +973 -0
- gams/transfer/syms/container_syms/_set.py +604 -0
- gams/transfer/syms/container_syms/_universe_alias.py +461 -0
- gams/transfer/syms/container_syms/_variable.py +321 -0
- gamsapi-52.5.0.dist-info/METADATA +150 -0
- gamsapi-52.5.0.dist-info/RECORD +257 -0
- gamsapi-52.5.0.dist-info/WHEEL +5 -0
- gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
- gamsapi-52.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
from ctypes import *
|
|
28
|
+
|
|
29
|
+
class Gdxencoding (ToolTemplate):
|
|
30
|
+
|
|
31
|
+
def __init__(self, system_directory, tool):
|
|
32
|
+
super().__init__(system_directory, tool)
|
|
33
|
+
self.title = 'gdxencoding: This converts the unique elements in the GDX file from one encoding to another one.'
|
|
34
|
+
self.add_posargdef('gdxFile', 'fnExist', 'Name of GDX file')
|
|
35
|
+
self.add_namedargdef('encodingIn=codingIn', 'str', 'Input encoding of GDX string', argdefault='latin_1')
|
|
36
|
+
self.add_namedargdef('encodingOut=codingOut', 'str', 'Output encoding of GDX string', argdefault='utf_8')
|
|
37
|
+
self.add_namedargdef('numConv=id', 'id.out:par:0','GAMS scalar symbol to store the number of actual conversions')
|
|
38
|
+
self.add_namedargdef('gdxOut=fileOut.gdx', 'fnWriteable', 'Name of GDX file that contains symbol numConv after execution')
|
|
39
|
+
|
|
40
|
+
def _get_last_gdx_error(self, gdx_handle, gdx):
|
|
41
|
+
from gams.core.gdx import GMS_SSSIZE
|
|
42
|
+
error_nr = gdx.c__gdxgetlasterror(gdx_handle)
|
|
43
|
+
error_msg = create_string_buffer(GMS_SSSIZE)
|
|
44
|
+
gdx.c__gdxerrorstr(gdx_handle, error_nr, error_msg)
|
|
45
|
+
return error_msg.value.decode('utf-8')
|
|
46
|
+
|
|
47
|
+
def execute(self):
|
|
48
|
+
if self.dohelp():
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
self.process_args()
|
|
52
|
+
gdxFile = self.posargs[0]
|
|
53
|
+
encodeIn = self.namedargs_val("encodingIn")
|
|
54
|
+
encodeOut = self.namedargs_val("encodingOut")
|
|
55
|
+
|
|
56
|
+
if self._tools._ecdb is None and 'numconv' in self.namedargs and not 'gdxout' in self.namedargs:
|
|
57
|
+
self.tool_error('Command line use requires gdxOut=<fileOut.gdx> if numConv=id is set')
|
|
58
|
+
|
|
59
|
+
import os
|
|
60
|
+
import sys
|
|
61
|
+
|
|
62
|
+
if sys.platform in ["linux", "linux2"]:
|
|
63
|
+
so_name = "libgdxcclib64.so"
|
|
64
|
+
elif sys.platform == "darwin":
|
|
65
|
+
so_name = "libgdxcclib64.dylib"
|
|
66
|
+
elif sys.platform == "win32":
|
|
67
|
+
so_name = "gdxcclib64.dll"
|
|
68
|
+
else:
|
|
69
|
+
raise Exception(f'unknown OS {sys.platform}')
|
|
70
|
+
gdx = cdll.LoadLibrary(os.path.join(self._tools._system_directory, so_name))
|
|
71
|
+
|
|
72
|
+
gdx_handle = c_void_p()
|
|
73
|
+
gdx.xcreate(byref(gdx_handle))
|
|
74
|
+
ival = c_int()
|
|
75
|
+
ival_p = byref(ival)
|
|
76
|
+
|
|
77
|
+
rc = gdx.c__gdxopenappend(gdx_handle, c_char_p(gdxFile.encode()), c_char_p(f'gdxService gdxEncoding {encodeIn} -> {encodeOut}'.encode()), ival_p)
|
|
78
|
+
if not rc == 1:
|
|
79
|
+
self.tool_error(f'Error gdxOpenAppend: {self._get_last_gdx_error(gdx_handle, gdx)}', print_help=False)
|
|
80
|
+
|
|
81
|
+
uel_nr = 1
|
|
82
|
+
num_conv = 0
|
|
83
|
+
uel = create_string_buffer(gdx.c__gdxuelmaxlength(gdx_handle)+1)
|
|
84
|
+
while True:
|
|
85
|
+
rc = gdx.c__gdxumuelget(gdx_handle, c_int(uel_nr), uel, ival_p)
|
|
86
|
+
if rc != 1: break
|
|
87
|
+
uel_out = uel.value.decode(encodeIn).encode(encodeOut)
|
|
88
|
+
if uel_out != uel.value:
|
|
89
|
+
if self._trace > 0:
|
|
90
|
+
self._tools.print_log(f'Converted {uel.value} to {uel_out}')
|
|
91
|
+
rc = gdx.c__gdxrenameuel(gdx_handle, uel.value, uel_out)
|
|
92
|
+
if not rc == 0:
|
|
93
|
+
self.tool_error(f'Error gdxRenameUEL: {self._get_last_gdx_error(gdx_handle, gdx)}', print_help=False)
|
|
94
|
+
num_conv += 1
|
|
95
|
+
uel_nr += 1
|
|
96
|
+
gdx.c__gdxclose(gdx_handle)
|
|
97
|
+
gdx.xfree(byref(gdx_handle))
|
|
98
|
+
|
|
99
|
+
if 'numconv' in self.namedargs:
|
|
100
|
+
import gams.transfer as gt
|
|
101
|
+
|
|
102
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
103
|
+
m.addParameter(self.namedargs_val("numconv"), records=num_conv)
|
|
104
|
+
self.write_id_outputs(m, self.namedargs_val("numconv"))
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Gdxrename (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'gdxrename: This renames the labels in the GDX file.'
|
|
33
|
+
self.add_posargdef('gdxFile', 'fnExist', 'Name of GDX file')
|
|
34
|
+
self.add_posargdef('mapSet', 'id.in:set:2','Set of labels to be used for renaming mapSet(*,*)')
|
|
35
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains map symbol "mapSet"', shell_req=True)
|
|
36
|
+
self.add_namedargdef('reverse=0|1', 'int', 'Determines if mapSet with record a.b leads to a replace of\na by b or to a replace of b by a', argdefault=0)
|
|
37
|
+
|
|
38
|
+
def execute(self):
|
|
39
|
+
if self.dohelp():
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
import gams.transfer as gt
|
|
43
|
+
|
|
44
|
+
self.process_args()
|
|
45
|
+
gdxFile, mapSet = self.posargs
|
|
46
|
+
reverse = self.namedargs_val("reverse")
|
|
47
|
+
|
|
48
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
49
|
+
self.read_id_inputs(m, mapSet)
|
|
50
|
+
|
|
51
|
+
# Make sure that mapSet is a 1-to-1 map so check for a->1 a->2 and a->1 b->1
|
|
52
|
+
m1 = {}
|
|
53
|
+
m2 = {}
|
|
54
|
+
for rec in m[mapSet].toList():
|
|
55
|
+
if reverse == 0:
|
|
56
|
+
a, b = rec[0], rec[1]
|
|
57
|
+
else:
|
|
58
|
+
b, a = rec[0], rec[1]
|
|
59
|
+
if m1.get(a,' ') == ' ':
|
|
60
|
+
m1[a] = b
|
|
61
|
+
else:
|
|
62
|
+
self.tool_error(f'mapSet "{mapSet}" is multimap "{a}" to "{m1[a]}" and "{b}"', print_help=False)
|
|
63
|
+
if m2.get(b,' ') == ' ':
|
|
64
|
+
m2[b] = a
|
|
65
|
+
else:
|
|
66
|
+
self.tool_error(f'mapSet "{mapSet}" is multimap "{b}" to "{m2[b]}" and "{a}"', print_help=False)
|
|
67
|
+
# Avoid a->b->c
|
|
68
|
+
for a, b in m1.items():
|
|
69
|
+
if not m1.get(b,' ') == ' ':
|
|
70
|
+
self.tool_error(f'mapSet "{mapSet}" has chain "{a}"->"{b}"->"{m1[b]}"', print_help=False)
|
|
71
|
+
|
|
72
|
+
# Apply map to gdxFile uels
|
|
73
|
+
import gams.core.gdx as gdx
|
|
74
|
+
h = gdx.new_gdxHandle_tp()
|
|
75
|
+
rc , msg = gdx.gdxCreate(h, gdx.GMS_SSSIZE)
|
|
76
|
+
if not rc == 1 or not len(msg) == 0:
|
|
77
|
+
self.tool_error(f'Error gdxCreate: rc={rc} msg={msg}', print_help=False)
|
|
78
|
+
|
|
79
|
+
if 0==gdx.gdxOpenAppend(h, gdxFile, 'gdxrename')[0]:
|
|
80
|
+
self.tool_error(f'Error gdxOpenAppend: {gdx.gdxErrorStr(h,gdx.gdxGetLastError(h))[1]}', print_help=False)
|
|
81
|
+
|
|
82
|
+
for a, b in m1.items():
|
|
83
|
+
rc = gdx.gdxRenameUEL(h, a, b);
|
|
84
|
+
if rc == -1:
|
|
85
|
+
self.tool_error(f'Error gdxRenameUEL: No UelTable', print_help=False)
|
|
86
|
+
elif rc in [0,2]: # everything ok, uel k does not exist
|
|
87
|
+
pass
|
|
88
|
+
elif rc == 3:
|
|
89
|
+
self.tool_error(f'Error gdxRenameUEL: Label "{b}" exists already', print_help=False)
|
|
90
|
+
else:
|
|
91
|
+
self.tool_error(f'Error gdxRenameUEL: Unknown return code rc={rc}', print_help=False)
|
|
92
|
+
|
|
93
|
+
gdx.gdxClose(h)
|
|
94
|
+
gdx.gdxFree(h)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Cholesky (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'cholesky: This calculates the Cholesky decomposition of a symmetric positive definite matrix A = LL^t.'
|
|
33
|
+
self.add_posargdef('i', 'id.in:set:1', 'Name of set used in matrix i(*)')
|
|
34
|
+
self.add_posargdef('A', 'id.in:par:2', 'Name of two-dimensional matrix parameter A(i,i)')
|
|
35
|
+
self.add_posargdef('L', 'id.out:par:2', 'Name of two-dimensional parameter containing the factor L(i,i)')
|
|
36
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains symbols i and A', shell_req=True)
|
|
37
|
+
self.add_namedargdef('gdxOut=fileOut.gdx','fnWriteable','Name of GDX file that contains symbol L after execution', shell_req=True)
|
|
38
|
+
|
|
39
|
+
def execute(self):
|
|
40
|
+
if self.dohelp():
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
import gams.transfer as gt
|
|
44
|
+
import numpy as np
|
|
45
|
+
|
|
46
|
+
self.process_args()
|
|
47
|
+
i, A, L = self.posargs
|
|
48
|
+
|
|
49
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
50
|
+
self.read_id_inputs(m, [i, A])
|
|
51
|
+
|
|
52
|
+
m[A].domain = [m[i],m[i]]
|
|
53
|
+
a = m[A].toDense()
|
|
54
|
+
upper = self.is_upper_matrix(a)
|
|
55
|
+
l = np.linalg.cholesky(a, upper=upper)
|
|
56
|
+
m.addParameter(L,[m[i],m[i]], records=l)
|
|
57
|
+
self.write_id_outputs(m, L)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Eigenvalue (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'eigenvalue: This calculates the Eigenvalues of a symmetric positive definite matrix.'
|
|
33
|
+
self.add_posargdef('i', 'id.in:set:1', 'Name of set used in matrix i(*)')
|
|
34
|
+
self.add_posargdef('A', 'id.in:par:2', 'Name of two-dimensional matrix parameter A(i,i)')
|
|
35
|
+
self.add_posargdef('AVal','id.out:par:1', 'Name of one-dimensional parameter to store the Eigenvalues AVal(i)')
|
|
36
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains symbols i and A', shell_req=True)
|
|
37
|
+
self.add_namedargdef('gdxOut=fileOut.gdx','fnWriteable','Name of GDX file that contains symbol AVal after execution', shell_req=True)
|
|
38
|
+
|
|
39
|
+
def execute(self):
|
|
40
|
+
if self.dohelp():
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
import gams.transfer as gt
|
|
44
|
+
import numpy as np
|
|
45
|
+
|
|
46
|
+
self.process_args()
|
|
47
|
+
i, A, AVal = self.posargs
|
|
48
|
+
|
|
49
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
50
|
+
self.read_id_inputs(m, [i, A])
|
|
51
|
+
m[A].domain = [m[i],m[i]]
|
|
52
|
+
a = m[A].toDense()
|
|
53
|
+
upper = self.is_upper_matrix(a)
|
|
54
|
+
eigval = np.linalg.eigvalsh(a, UPLO="U" if upper else "L")
|
|
55
|
+
m.addParameter(AVal,[m[i]], records=eigval)
|
|
56
|
+
self.write_id_outputs(m, AVal)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Eigenvector (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'eigenvector: This calculates the Eigenvalues and Eigenvecors of a symmetric positive definite matrix.'
|
|
33
|
+
self.add_posargdef('i', 'id.in:set:1', 'Name of set used in matrix i(*)')
|
|
34
|
+
self.add_posargdef('A', 'id.in:par:2', 'Name of two-dimensional matrix parameter A(i,i)')
|
|
35
|
+
self.add_posargdef('AVal','id.out:par:1', 'Name of one-dimensional parameter to store the Eigenvalues AVal(i)')
|
|
36
|
+
self.add_posargdef('AVec','id.out:par:2', 'Name of two-dimensional matrix to store the Eigenvectors AVec(i,i)')
|
|
37
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains symbols i and A', shell_req=True)
|
|
38
|
+
self.add_namedargdef('gdxOut=fileOut.gdx','fnWriteable','Name of GDX file that contains symbols Aval and AVec after execution', shell_req=True)
|
|
39
|
+
|
|
40
|
+
def execute(self):
|
|
41
|
+
if self.dohelp():
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
import gams.transfer as gt
|
|
45
|
+
import numpy as np
|
|
46
|
+
|
|
47
|
+
self.process_args()
|
|
48
|
+
i, A, AVal, AVec= self.posargs
|
|
49
|
+
|
|
50
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
51
|
+
self.read_id_inputs(m, [i, A])
|
|
52
|
+
m[A].domain = [m[i],m[i]]
|
|
53
|
+
a = m[A].toDense()
|
|
54
|
+
upper = self.is_upper_matrix(a)
|
|
55
|
+
eigval, eigvec = np.linalg.eigh(a, UPLO="U" if upper else "L")
|
|
56
|
+
m.addParameter(AVal,[m[i]], records=eigval)
|
|
57
|
+
m.addParameter(AVec,[m[i],m[i]], records=eigvec)
|
|
58
|
+
self.write_id_outputs(m, [AVal, AVec])
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Invert (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'invert: This calculates the inverse of a square matrix A: A*AInv = I.'
|
|
33
|
+
self.add_posargdef('i', 'id.in:set:1', 'Name of set used in matrix i(*)')
|
|
34
|
+
self.add_posargdef('A', 'id.in:par:2', 'Name of two-dimensional matrix parameter A(i,i)')
|
|
35
|
+
self.add_posargdef('AInv','id.out:par:2', 'Name of two-dimensional parameter containing the inverse AInv(i,i)')
|
|
36
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains symbols i and A', shell_req=True)
|
|
37
|
+
self.add_namedargdef('gdxOut=fileOut.gdx','fnWriteable','Name of GDX file that contains symbol AInv after execution', shell_req=True)
|
|
38
|
+
|
|
39
|
+
def execute(self):
|
|
40
|
+
if self.dohelp():
|
|
41
|
+
return
|
|
42
|
+
|
|
43
|
+
import gams.transfer as gt
|
|
44
|
+
import numpy as np
|
|
45
|
+
|
|
46
|
+
self.process_args()
|
|
47
|
+
i, A, AInv = self.posargs
|
|
48
|
+
|
|
49
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
50
|
+
self.read_id_inputs(m, [i, A])
|
|
51
|
+
|
|
52
|
+
m[A].domain = [m[i],m[i]]
|
|
53
|
+
inv = np.linalg.inv(m[A].toDense())
|
|
54
|
+
m.addParameter(AInv,[m[i],m[i]], records=inv)
|
|
55
|
+
self.write_id_outputs(m, AInv)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
|
|
28
|
+
class Ols (ToolTemplate):
|
|
29
|
+
|
|
30
|
+
def __init__(self, system_directory, tool):
|
|
31
|
+
super().__init__(system_directory, tool)
|
|
32
|
+
self.title = 'ols: This estimates the unknown parameters in a linear regression model.'
|
|
33
|
+
self.add_posargdef('i', 'id.in:set:1', 'Name of set of observations i(*)')
|
|
34
|
+
self.add_posargdef('p', 'id.in:set:1', 'Name of set of estimates p(*)')
|
|
35
|
+
self.add_posargdef('A', 'id.in:par:2', 'Name of two-dimensional explanatory variable matrix A(i,p)')
|
|
36
|
+
self.add_posargdef('y', 'id.in:par:1', 'Name of one-dimensional dependent variable y(i)')
|
|
37
|
+
self.add_posargdef('est', 'id.out:par:1', 'Name of one-dimensional estimated statistical coefficients est(p)')
|
|
38
|
+
self.add_namedargdef('gdxIn=fileIn.gdx', 'fnExist', 'Name of GDX file that contains symbols i, p, A, and y', shell_req=True)
|
|
39
|
+
self.add_namedargdef('gdxOut=fileOut.gdx','fnWriteable','Name of GDX file that contains symbol est and info symbols after execution', shell_req=True)
|
|
40
|
+
self.add_namedargdef('intercept=0|1|2','int','Choice for constant term\n0 - no constant term or intercept will be added to the problem\n1 - a constant term will always be added\n2 - the algorithm will add a constant term only if there is\n no data column with all ones in the matrix A', argdefault=2)
|
|
41
|
+
self.add_namedargdef('rcond=val','float','Cut-off ratio for small singular values of A used as\nargument rcond to np.linalg.lstsq', argdefault=-1.0)
|
|
42
|
+
self.add_namedargdef('covar=id','id.out:par:2','Statistical info: variance-covariance matrix CoVar(p,p)')
|
|
43
|
+
self.add_namedargdef('df=id','id.out:par:0','Statistical info: degrees of freedom (scalar)')
|
|
44
|
+
self.add_namedargdef('fitted=id','id.out:par:1','Statistical info: fitted values for dependent variable fitted(i)')
|
|
45
|
+
self.add_namedargdef('r2=id','id.out:par:0','Statistical info: R squared (scalar)')
|
|
46
|
+
self.add_namedargdef('resid=id','id.out:par:1','Statistical info: residuals resid(i)')
|
|
47
|
+
self.add_namedargdef('resvar=id','id.out:par:0','Statistical info: residual variance (scalar)')
|
|
48
|
+
self.add_namedargdef('rss=id','id.out:par:0','Statistical info: residual sum of squares (scalar)')
|
|
49
|
+
self.add_namedargdef('se=id','id.out:par:1','Statistical info: standard errors se(p)')
|
|
50
|
+
self.add_namedargdef('sigma=id','id.out:par:0','Statistical info: standard error (scalar)')
|
|
51
|
+
self.add_namedargdef('tval=id','id.out:par:1','Statistical info: standard errors se(p)')
|
|
52
|
+
self._export = []
|
|
53
|
+
|
|
54
|
+
def add_to_output(self, m, key, domain=None, recs=None):
|
|
55
|
+
if key in self.namedargs:
|
|
56
|
+
id = self.namedargs[key]
|
|
57
|
+
self._export.append(id)
|
|
58
|
+
if domain is None:
|
|
59
|
+
m.addParameter(id, records=recs)
|
|
60
|
+
else:
|
|
61
|
+
m.addParameter(id, domain, records=recs)
|
|
62
|
+
|
|
63
|
+
def execute(self):
|
|
64
|
+
if self.dohelp():
|
|
65
|
+
return
|
|
66
|
+
import gams.transfer as gt
|
|
67
|
+
import numpy as np
|
|
68
|
+
self.process_args()
|
|
69
|
+
i, p, A, y, est = self.posargs
|
|
70
|
+
|
|
71
|
+
m = gt.Container(system_directory=self._system_directory)
|
|
72
|
+
self.read_id_inputs(m, [i, p, A, y])
|
|
73
|
+
|
|
74
|
+
m[A].domain = [m[i],m[p]]
|
|
75
|
+
m[y].domain = [m[i]]
|
|
76
|
+
a = m[A].toDense()
|
|
77
|
+
Y = m[y].toDense()
|
|
78
|
+
|
|
79
|
+
rb = None
|
|
80
|
+
rcond = self.namedargs_val("rcond")
|
|
81
|
+
intercept = self.namedargs_val("intercept")
|
|
82
|
+
need_intercept = True if intercept in [1,2] else False
|
|
83
|
+
if intercept == 2:
|
|
84
|
+
for c in range(a.shape[1]):
|
|
85
|
+
if np.all(a[:,c] == 1):
|
|
86
|
+
need_intercept = False
|
|
87
|
+
break
|
|
88
|
+
if need_intercept:
|
|
89
|
+
self._tools.print_log('Intercept added')
|
|
90
|
+
rb = -1
|
|
91
|
+
o = np.ones((a.shape[0], 1))
|
|
92
|
+
a = np.append(a, o, axis=1)
|
|
93
|
+
|
|
94
|
+
mm = a.shape[0]
|
|
95
|
+
nn = a.shape[1]
|
|
96
|
+
x, rss = np.linalg.lstsq(a, Y, rcond=rcond)[:2]
|
|
97
|
+
fitted = np.matmul(a, x)
|
|
98
|
+
residuals = Y - fitted
|
|
99
|
+
df = mm - nn
|
|
100
|
+
if df <= 0:
|
|
101
|
+
self.tool_error(f'Degrees of freedom df=m-n should be >0, is {mm}-{nn}={df}', print_help=False)
|
|
102
|
+
resvar = rss[0]/df
|
|
103
|
+
sigma = np.sqrt(resvar)
|
|
104
|
+
meanf = np.sum(fitted)/mm
|
|
105
|
+
mss = np.dot(fitted-meanf, fitted-meanf)
|
|
106
|
+
r2 = mss/(mss+rss[0])
|
|
107
|
+
|
|
108
|
+
if 'se' in self.namedargs or 'covar' in self.namedargs or 'tval' in self.namedargs:
|
|
109
|
+
try:
|
|
110
|
+
MSE = (sum((Y-fitted)**2))/df
|
|
111
|
+
ainv = np.linalg.inv(np.dot(a.T,a))
|
|
112
|
+
var_b = MSE*(ainv.diagonal())
|
|
113
|
+
if len([v for v in var_b if v < 0]):
|
|
114
|
+
self.tool_error('Unexpected negative values in var_b', print_help=False)
|
|
115
|
+
se = np.sqrt(var_b)
|
|
116
|
+
tval = x / se
|
|
117
|
+
covar = ainv*resvar
|
|
118
|
+
except Exception as e:
|
|
119
|
+
self._tools.print_log(str(e))
|
|
120
|
+
if not np.allclose(np.dot(np.dot(a.T,a), ainv), np.eye(ainv.shape[0])):
|
|
121
|
+
self._tools.print_log(f'Inversion of matrix failed. Condition number: {np.linalg.cond(np.dot(a.T,a))}')
|
|
122
|
+
se = []
|
|
123
|
+
tval = []
|
|
124
|
+
covar = []
|
|
125
|
+
m.addParameter(est,[m[p]], records=x[:rb])
|
|
126
|
+
self._export.append(est)
|
|
127
|
+
if 'covar' in self.namedargs: self.add_to_output(m,'covar' , [m[p],m[p]], recs=covar[:rb,:rb])
|
|
128
|
+
if 'df' in self.namedargs: self.add_to_output(m,'df' , recs=df)
|
|
129
|
+
if 'fitted' in self.namedargs: self.add_to_output(m,'fitted', [m[i]], recs=fitted)
|
|
130
|
+
if 'r2' in self.namedargs: self.add_to_output(m,'r2' , recs=r2)
|
|
131
|
+
if 'resid' in self.namedargs: self.add_to_output(m,'resid' , [m[i]], recs=residuals)
|
|
132
|
+
if 'resvar' in self.namedargs: self.add_to_output(m,'resvar', recs=resvar)
|
|
133
|
+
if 'rss' in self.namedargs: self.add_to_output(m,'rss' , recs=rss[0])
|
|
134
|
+
if 'se' in self.namedargs: self.add_to_output(m,'se' , [m[p]], recs=se[:rb])
|
|
135
|
+
if 'sigma' in self.namedargs: self.add_to_output(m,'sigma' , recs=sigma)
|
|
136
|
+
if 'tval' in self.namedargs: self.add_to_output(m,'tval' , [m[p]], recs=tval[:rb])
|
|
137
|
+
|
|
138
|
+
self.write_id_outputs(m, self._export)
|