ltbams 0.9.9__py3-none-any.whl → 1.0.2a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. ams/__init__.py +4 -11
  2. ams/_version.py +3 -3
  3. ams/cases/5bus/pjm5bus_demo.xlsx +0 -0
  4. ams/cases/5bus/pjm5bus_jumper.xlsx +0 -0
  5. ams/cases/5bus/pjm5bus_uced.json +1062 -0
  6. ams/cases/5bus/pjm5bus_uced.xlsx +0 -0
  7. ams/cases/5bus/pjm5bus_uced_esd1.xlsx +0 -0
  8. ams/cases/5bus/pjm5bus_uced_ev.xlsx +0 -0
  9. ams/cases/ieee123/ieee123.xlsx +0 -0
  10. ams/cases/ieee123/ieee123_regcv1.xlsx +0 -0
  11. ams/cases/ieee14/ieee14.json +1166 -0
  12. ams/cases/ieee14/ieee14.raw +92 -0
  13. ams/cases/ieee14/ieee14_conn.xlsx +0 -0
  14. ams/cases/ieee14/ieee14_uced.xlsx +0 -0
  15. ams/cases/ieee39/ieee39.xlsx +0 -0
  16. ams/cases/ieee39/ieee39_uced.xlsx +0 -0
  17. ams/cases/ieee39/ieee39_uced_esd1.xlsx +0 -0
  18. ams/cases/ieee39/ieee39_uced_pvd1.xlsx +0 -0
  19. ams/cases/ieee39/ieee39_uced_vis.xlsx +0 -0
  20. ams/cases/matpower/benchmark.json +1594 -0
  21. ams/cases/matpower/case118.m +787 -0
  22. ams/cases/matpower/case14.m +129 -0
  23. ams/cases/matpower/case300.m +1315 -0
  24. ams/cases/matpower/case39.m +205 -0
  25. ams/cases/matpower/case5.m +62 -0
  26. ams/cases/matpower/case_ACTIVSg2000.m +9460 -0
  27. ams/cases/npcc/npcc.m +644 -0
  28. ams/cases/npcc/npcc_uced.xlsx +0 -0
  29. ams/cases/pglib/pglib_opf_case39_epri__api.m +243 -0
  30. ams/cases/wecc/wecc.m +714 -0
  31. ams/cases/wecc/wecc_uced.xlsx +0 -0
  32. ams/cli.py +6 -0
  33. ams/core/__init__.py +2 -0
  34. ams/core/documenter.py +652 -0
  35. ams/core/matprocessor.py +782 -0
  36. ams/core/model.py +330 -0
  37. ams/core/param.py +322 -0
  38. ams/core/service.py +918 -0
  39. ams/core/symprocessor.py +224 -0
  40. ams/core/var.py +59 -0
  41. ams/extension/__init__.py +5 -0
  42. ams/extension/eva.py +401 -0
  43. ams/interface.py +1085 -0
  44. ams/io/__init__.py +133 -0
  45. ams/io/json.py +82 -0
  46. ams/io/matpower.py +406 -0
  47. ams/io/psse.py +6 -0
  48. ams/io/pypower.py +103 -0
  49. ams/io/xlsx.py +80 -0
  50. ams/main.py +81 -4
  51. ams/models/__init__.py +24 -0
  52. ams/models/area.py +40 -0
  53. ams/models/bus.py +52 -0
  54. ams/models/cost.py +169 -0
  55. ams/models/distributed/__init__.py +3 -0
  56. ams/models/distributed/esd1.py +71 -0
  57. ams/models/distributed/ev.py +60 -0
  58. ams/models/distributed/pvd1.py +67 -0
  59. ams/models/group.py +231 -0
  60. ams/models/info.py +26 -0
  61. ams/models/line.py +238 -0
  62. ams/models/renewable/__init__.py +5 -0
  63. ams/models/renewable/regc.py +119 -0
  64. ams/models/reserve.py +94 -0
  65. ams/models/shunt.py +14 -0
  66. ams/models/static/__init__.py +2 -0
  67. ams/models/static/gen.py +165 -0
  68. ams/models/static/pq.py +61 -0
  69. ams/models/timeslot.py +69 -0
  70. ams/models/zone.py +49 -0
  71. ams/opt/__init__.py +12 -0
  72. ams/opt/constraint.py +175 -0
  73. ams/opt/exprcalc.py +127 -0
  74. ams/opt/expression.py +188 -0
  75. ams/opt/objective.py +174 -0
  76. ams/opt/omodel.py +432 -0
  77. ams/opt/optzbase.py +192 -0
  78. ams/opt/param.py +156 -0
  79. ams/opt/var.py +233 -0
  80. ams/pypower/__init__.py +8 -0
  81. ams/pypower/_compat.py +9 -0
  82. ams/pypower/core/__init__.py +8 -0
  83. ams/pypower/core/pips.py +894 -0
  84. ams/pypower/core/ppoption.py +244 -0
  85. ams/pypower/core/ppver.py +18 -0
  86. ams/pypower/core/solver.py +2451 -0
  87. ams/pypower/eps.py +6 -0
  88. ams/pypower/idx.py +174 -0
  89. ams/pypower/io.py +604 -0
  90. ams/pypower/make/__init__.py +11 -0
  91. ams/pypower/make/matrices.py +665 -0
  92. ams/pypower/make/pdv.py +506 -0
  93. ams/pypower/routines/__init__.py +7 -0
  94. ams/pypower/routines/cpf.py +513 -0
  95. ams/pypower/routines/cpf_callbacks.py +114 -0
  96. ams/pypower/routines/opf.py +1803 -0
  97. ams/pypower/routines/opffcns.py +1946 -0
  98. ams/pypower/routines/pflow.py +852 -0
  99. ams/pypower/toggle.py +1098 -0
  100. ams/pypower/utils.py +293 -0
  101. ams/report.py +212 -50
  102. ams/routines/__init__.py +23 -0
  103. ams/routines/acopf.py +117 -0
  104. ams/routines/cpf.py +65 -0
  105. ams/routines/dcopf.py +241 -0
  106. ams/routines/dcpf.py +209 -0
  107. ams/routines/dcpf0.py +196 -0
  108. ams/routines/dopf.py +150 -0
  109. ams/routines/ed.py +312 -0
  110. ams/routines/pflow.py +255 -0
  111. ams/routines/pflow0.py +113 -0
  112. ams/routines/routine.py +1033 -0
  113. ams/routines/rted.py +519 -0
  114. ams/routines/type.py +160 -0
  115. ams/routines/uc.py +376 -0
  116. ams/shared.py +63 -9
  117. ams/system.py +61 -22
  118. ams/utils/__init__.py +3 -0
  119. ams/utils/misc.py +77 -0
  120. ams/utils/paths.py +257 -0
  121. docs/Makefile +21 -0
  122. docs/make.bat +35 -0
  123. docs/source/_templates/autosummary/base.rst +5 -0
  124. docs/source/_templates/autosummary/class.rst +35 -0
  125. docs/source/_templates/autosummary/module.rst +65 -0
  126. docs/source/_templates/autosummary/module_toctree.rst +66 -0
  127. docs/source/api.rst +102 -0
  128. docs/source/conf.py +203 -0
  129. docs/source/examples/index.rst +34 -0
  130. docs/source/genmodelref.py +61 -0
  131. docs/source/genroutineref.py +47 -0
  132. docs/source/getting_started/copyright.rst +20 -0
  133. docs/source/getting_started/formats/index.rst +20 -0
  134. docs/source/getting_started/formats/matpower.rst +183 -0
  135. docs/source/getting_started/formats/psse.rst +46 -0
  136. docs/source/getting_started/formats/pypower.rst +223 -0
  137. docs/source/getting_started/formats/xlsx.png +0 -0
  138. docs/source/getting_started/formats/xlsx.rst +23 -0
  139. docs/source/getting_started/index.rst +76 -0
  140. docs/source/getting_started/install.rst +234 -0
  141. docs/source/getting_started/overview.rst +26 -0
  142. docs/source/getting_started/testcase.rst +45 -0
  143. docs/source/getting_started/verification.rst +13 -0
  144. docs/source/images/curent.ico +0 -0
  145. docs/source/images/dcopf_time.png +0 -0
  146. docs/source/images/sponsors/CURENT_Logo_NameOnTrans.png +0 -0
  147. docs/source/images/sponsors/CURENT_Logo_Transparent.png +0 -0
  148. docs/source/images/sponsors/CURENT_Logo_Transparent_Name.png +0 -0
  149. docs/source/images/sponsors/doe.png +0 -0
  150. docs/source/index.rst +108 -0
  151. docs/source/modeling/example.rst +159 -0
  152. docs/source/modeling/index.rst +17 -0
  153. docs/source/modeling/model.rst +210 -0
  154. docs/source/modeling/routine.rst +122 -0
  155. docs/source/modeling/system.rst +51 -0
  156. docs/source/release-notes.rst +398 -0
  157. ltbams-1.0.2a1.dist-info/METADATA +210 -0
  158. ltbams-1.0.2a1.dist-info/RECORD +188 -0
  159. {ltbams-0.9.9.dist-info → ltbams-1.0.2a1.dist-info}/WHEEL +1 -1
  160. ltbams-1.0.2a1.dist-info/top_level.txt +3 -0
  161. tests/__init__.py +0 -0
  162. tests/test_1st_system.py +33 -0
  163. tests/test_addressing.py +40 -0
  164. tests/test_andes_mats.py +61 -0
  165. tests/test_case.py +266 -0
  166. tests/test_cli.py +34 -0
  167. tests/test_export_csv.py +89 -0
  168. tests/test_group.py +83 -0
  169. tests/test_interface.py +216 -0
  170. tests/test_io.py +32 -0
  171. tests/test_jumper.py +27 -0
  172. tests/test_known_good.py +267 -0
  173. tests/test_matp.py +437 -0
  174. tests/test_model.py +54 -0
  175. tests/test_omodel.py +119 -0
  176. tests/test_paths.py +22 -0
  177. tests/test_report.py +251 -0
  178. tests/test_repr.py +21 -0
  179. tests/test_routine.py +178 -0
  180. tests/test_rtn_dcopf.py +101 -0
  181. tests/test_rtn_dcpf.py +77 -0
  182. tests/test_rtn_ed.py +279 -0
  183. tests/test_rtn_pflow.py +219 -0
  184. tests/test_rtn_rted.py +273 -0
  185. tests/test_rtn_uc.py +248 -0
  186. tests/test_service.py +73 -0
  187. ltbams-0.9.9.dist-info/LICENSE +0 -692
  188. ltbams-0.9.9.dist-info/METADATA +0 -859
  189. ltbams-0.9.9.dist-info/RECORD +0 -14
  190. ltbams-0.9.9.dist-info/top_level.txt +0 -1
  191. {ltbams-0.9.9.dist-info → ltbams-1.0.2a1.dist-info}/entry_points.txt +0 -0
ams/opt/param.py ADDED
@@ -0,0 +1,156 @@
1
+ """
2
+ Module for optimization Param.
3
+ """
4
+ import logging
5
+
6
+ from typing import Optional
7
+ from collections import OrderedDict
8
+ import re
9
+
10
+ import numpy as np
11
+
12
+ from andes.core.common import Config
13
+
14
+ import cvxpy as cp
15
+
16
+ from ams.shared import sps
17
+
18
+ from ams.opt import OptzBase, ensure_symbols, ensure_mats_and_parsed
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class Param(OptzBase):
24
+ """
25
+ Base class for parameters used in a routine.
26
+
27
+ Parameters
28
+ ----------
29
+ no_parse: bool, optional
30
+ True to skip parsing the parameter.
31
+ nonneg: bool, optional
32
+ True to set the parameter as non-negative.
33
+ nonpos: bool, optional
34
+ True to set the parameter as non-positive.
35
+ cplx: bool, optional
36
+ True to set the parameter as complex, avoiding the use of `complex`.
37
+ imag: bool, optional
38
+ True to set the parameter as imaginary.
39
+ symmetric: bool, optional
40
+ True to set the parameter as symmetric.
41
+ diag: bool, optional
42
+ True to set the parameter as diagonal.
43
+ hermitian: bool, optional
44
+ True to set the parameter as hermitian.
45
+ boolean: bool, optional
46
+ True to set the parameter as boolean.
47
+ integer: bool, optional
48
+ True to set the parameter as integer.
49
+ pos: bool, optional
50
+ True to set the parameter as positive.
51
+ neg: bool, optional
52
+ True to set the parameter as negative.
53
+ sparse: bool, optional
54
+ True to set the parameter as sparse.
55
+ """
56
+
57
+ def __init__(self,
58
+ name: Optional[str] = None,
59
+ info: Optional[str] = None,
60
+ unit: Optional[str] = None,
61
+ no_parse: Optional[bool] = False,
62
+ nonneg: Optional[bool] = False,
63
+ nonpos: Optional[bool] = False,
64
+ cplx: Optional[bool] = False,
65
+ imag: Optional[bool] = False,
66
+ symmetric: Optional[bool] = False,
67
+ diag: Optional[bool] = False,
68
+ hermitian: Optional[bool] = False,
69
+ boolean: Optional[bool] = False,
70
+ integer: Optional[bool] = False,
71
+ pos: Optional[bool] = False,
72
+ neg: Optional[bool] = False,
73
+ sparse: Optional[bool] = False,
74
+ ):
75
+ OptzBase.__init__(self, name=name, info=info, unit=unit)
76
+ self.no_parse = no_parse # True to skip parsing the parameter
77
+ self.sparse = sparse
78
+
79
+ self.config = Config(name=self.class_name) # `config` that can be exported
80
+
81
+ self.config.add(OrderedDict((('nonneg', nonneg),
82
+ ('nonpos', nonpos),
83
+ ('complex', cplx),
84
+ ('imag', imag),
85
+ ('symmetric', symmetric),
86
+ ('diag', diag),
87
+ ('hermitian', hermitian),
88
+ ('boolean', boolean),
89
+ ('integer', integer),
90
+ ('pos', pos),
91
+ ('neg', neg),
92
+ )))
93
+
94
+ @ensure_symbols
95
+ def parse(self):
96
+ """
97
+ Parse the parameter.
98
+
99
+ Returns
100
+ -------
101
+ bool
102
+ Returns True if the parsing is successful, False otherwise.
103
+ """
104
+ sub_map = self.om.rtn.syms.sub_map
105
+ code_param = "param(**config)"
106
+ for pattern, replacement, in sub_map.items():
107
+ try:
108
+ code_param = re.sub(pattern, replacement, code_param)
109
+ except Exception as e:
110
+ raise Exception(f"Error in parsing param <{self.name}>.\n{e}")
111
+ self.code = code_param
112
+ return True
113
+
114
+ @ensure_mats_and_parsed
115
+ def evaluate(self):
116
+ """
117
+ Evaluate the parameter.
118
+ """
119
+ if self.no_parse:
120
+ return True
121
+
122
+ config = self.config.as_dict()
123
+ try:
124
+ msg = f"Parameter <{self.name}> is set as sparse, "
125
+ msg += "but the value is not sparse."
126
+ if self.sparse:
127
+ self.v = sps.csr_matrix(self.v)
128
+
129
+ # Create the cvxpy.Parameter object
130
+ if isinstance(self.v, np.ndarray):
131
+ self.optz = cp.Parameter(shape=self.v.shape, **config)
132
+ else:
133
+ self.optz = cp.Parameter(**config)
134
+ self.optz.value = self.v
135
+ except ValueError:
136
+ msg = f"Parameter <{self.name}> has non-numeric value, "
137
+ msg += "set `no_parse=True`."
138
+ logger.warning(msg)
139
+ self.no_parse = True
140
+ return True
141
+ except Exception as e:
142
+ raise Exception(f"Error in evaluating Param <{self.name}>.\n{e}")
143
+ return True
144
+
145
+ def update(self):
146
+ """
147
+ Update the Parameter value.
148
+ """
149
+ # NOTE: skip no_parse parameters
150
+ if self.optz is None:
151
+ return None
152
+ self.optz.value = self.v
153
+ return True
154
+
155
+ def __repr__(self):
156
+ return f'{self.__class__.__name__}: {self.name}'
ams/opt/var.py ADDED
@@ -0,0 +1,233 @@
1
+ """
2
+ Module for optimization Var.
3
+ """
4
+ import logging
5
+
6
+ from typing import Optional, Union
7
+ from collections import OrderedDict
8
+ import re
9
+
10
+ import numpy as np
11
+
12
+ from andes.core.common import Config
13
+
14
+ import cvxpy as cp
15
+
16
+ from ams.utils import pretty_long_message
17
+ from ams.shared import _prefix, _max_length
18
+
19
+ from ams.opt import OptzBase, ensure_symbols, ensure_mats_and_parsed
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class Var(OptzBase):
25
+ """
26
+ Base class for variables used in a routine.
27
+
28
+ When `horizon` is provided, the variable will be expanded to a matrix,
29
+ where rows are indexed by the source variable index and columns are
30
+ indexed by the horizon index.
31
+
32
+ Parameters
33
+ ----------
34
+ info : str, optional
35
+ Descriptive information
36
+ unit : str, optional
37
+ Unit
38
+ tex_name : str
39
+ LaTeX-formatted variable symbol. Defaults to the value of ``name``.
40
+ name : str, optional
41
+ Variable name. One should typically assigning the name directly because
42
+ it will be automatically assigned by the model. The value of ``name``
43
+ will be the symbol name to be used in expressions.
44
+ src : str, optional
45
+ Source variable name. Defaults to the value of ``name``.
46
+ model : str, optional
47
+ Name of the owner model or group.
48
+ horizon : ams.routines.RParam, optional
49
+ Horizon idx.
50
+ nonneg : bool, optional
51
+ Non-negative variable
52
+ nonpos : bool, optional
53
+ Non-positive variable
54
+ cplx : bool, optional
55
+ Complex variable
56
+ imag : bool, optional
57
+ Imaginary variable
58
+ symmetric : bool, optional
59
+ Symmetric variable
60
+ diag : bool, optional
61
+ Diagonal variable
62
+ psd : bool, optional
63
+ Positive semi-definite variable
64
+ nsd : bool, optional
65
+ Negative semi-definite variable
66
+ hermitian : bool, optional
67
+ Hermitian variable
68
+ boolean : bool, optional
69
+ Boolean variable
70
+ integer : bool, optional
71
+ Integer variable
72
+ pos : bool, optional
73
+ Positive variable
74
+ neg : bool, optional
75
+ Negative variable
76
+
77
+ Attributes
78
+ ----------
79
+ a : np.ndarray
80
+ Variable address.
81
+ _v : np.ndarray
82
+ Local-storage of the variable value.
83
+ rtn : ams.routines.Routine
84
+ The owner routine instance.
85
+ """
86
+
87
+ def __init__(self,
88
+ name: Optional[str] = None,
89
+ tex_name: Optional[str] = None,
90
+ info: Optional[str] = None,
91
+ src: Optional[str] = None,
92
+ unit: Optional[str] = None,
93
+ model: Optional[str] = None,
94
+ shape: Optional[Union[tuple, int]] = None,
95
+ v0: Optional[str] = None,
96
+ horizon: Optional[str] = None,
97
+ nonneg: Optional[bool] = False,
98
+ nonpos: Optional[bool] = False,
99
+ cplx: Optional[bool] = False,
100
+ imag: Optional[bool] = False,
101
+ symmetric: Optional[bool] = False,
102
+ diag: Optional[bool] = False,
103
+ psd: Optional[bool] = False,
104
+ nsd: Optional[bool] = False,
105
+ hermitian: Optional[bool] = False,
106
+ boolean: Optional[bool] = False,
107
+ integer: Optional[bool] = False,
108
+ pos: Optional[bool] = False,
109
+ neg: Optional[bool] = False,
110
+ ):
111
+ self.name = name
112
+ self.info = info
113
+ self.unit = unit
114
+
115
+ self.tex_name = tex_name if tex_name else name
116
+ # variable internal index inside a model (assigned in run time)
117
+ self.id = None
118
+ OptzBase.__init__(self, name=name, info=info, unit=unit, model=model)
119
+ self.src = src
120
+ self.v0 = v0
121
+ self.horizon = horizon
122
+ self._shape = shape
123
+ self._v = None
124
+ self.a: np.ndarray = np.array([], dtype=int)
125
+
126
+ self.config = Config(name=self.class_name) # `config` that can be exported
127
+
128
+ self.config.add(OrderedDict((('nonneg', nonneg),
129
+ ('nonpos', nonpos),
130
+ ('complex', cplx),
131
+ ('imag', imag),
132
+ ('symmetric', symmetric),
133
+ ('diag', diag),
134
+ ('psd', psd),
135
+ ('nsd', nsd),
136
+ ('hermitian', hermitian),
137
+ ('boolean', boolean),
138
+ ('integer', integer),
139
+ ('pos', pos),
140
+ ('neg', neg),
141
+ )))
142
+
143
+ @property
144
+ def v(self):
145
+ """
146
+ Return the CVXPY variable value.
147
+ """
148
+ if self.optz is None:
149
+ return None
150
+ if self.optz.value is None:
151
+ try:
152
+ shape = self.optz.shape
153
+ return np.zeros(shape)
154
+ except AttributeError:
155
+ return None
156
+ else:
157
+ return self.optz.value
158
+
159
+ @v.setter
160
+ def v(self, value):
161
+ if self.optz is None:
162
+ logger.info(f"Variable <{self.name}> is not initialized yet.")
163
+ else:
164
+ self.optz.value = value
165
+
166
+ @ensure_symbols
167
+ def parse(self):
168
+ """
169
+ Parse the variable.
170
+ """
171
+ sub_map = self.om.rtn.syms.sub_map
172
+ # NOTE: number of rows is the size of the source variable
173
+ if self.owner is not None:
174
+ nr = self.owner.n
175
+ nc = 0
176
+ if self.horizon:
177
+ # NOTE: numer of columns is the horizon if exists
178
+ nc = int(self.horizon.n)
179
+ shape = (nr, nc)
180
+ else:
181
+ shape = (nr,)
182
+ elif isinstance(self._shape, int):
183
+ shape = (self._shape,)
184
+ nr = shape
185
+ nc = 0
186
+ elif isinstance(self._shape, tuple):
187
+ shape = self._shape
188
+ nr = shape[0]
189
+ nc = shape[1] if len(shape) > 1 else 0
190
+ else:
191
+ raise ValueError(f"Invalid shape {self._shape}.")
192
+ code_var = f"var({shape}, **config)"
193
+ logger.debug(f" - Var <{self.name}>: {self.code}")
194
+ for pattern, replacement, in sub_map.items():
195
+ try:
196
+ code_var = re.sub(pattern, replacement, code_var)
197
+ except Exception as e:
198
+ raise Exception(f"Error in parsing var <{self.name}>.\n{e}")
199
+ self.code = code_var
200
+ return True
201
+
202
+ @ensure_mats_and_parsed
203
+ def evaluate(self):
204
+ """
205
+ Evaluate the variable.
206
+
207
+ Returns
208
+ -------
209
+ bool
210
+ Returns True if the evaluation is successful, False otherwise.
211
+ """
212
+ # NOTE: in CVXPY, Config only allow lower case letters
213
+ config = {} # used in `self.code`
214
+ for k, v in self.config.as_dict().items():
215
+ if k == 'psd':
216
+ config['PSD'] = v
217
+ elif k == 'nsd':
218
+ config['NSD'] = v
219
+ elif k == 'bool':
220
+ config['boolean'] = v
221
+ else:
222
+ config[k] = v
223
+ msg = f" - Var <{self.name}>: {self.code}"
224
+ logger.debug(pretty_long_message(msg, _prefix, max_length=_max_length))
225
+ try:
226
+ local_vars = {'self': self, 'config': config, 'cp': cp}
227
+ self.optz = eval(self.code, {}, local_vars)
228
+ except Exception as e:
229
+ raise Exception(f"Error in evaluating Var <{self.name}>.\n{e}")
230
+ return True
231
+
232
+ def __repr__(self):
233
+ return f'{self.__class__.__name__}: {self.owner.__class__.__name__}.{self.name}'
@@ -0,0 +1,8 @@
1
+ """
2
+ Revised PYPOWER module.
3
+ """
4
+
5
+ from ams.pypower import utils, make, routines # NOQA
6
+ from ams.pypower.routines.opf import runopf, runuopf # NOQA
7
+ from ams.pypower.routines import runpf # NOQA
8
+ from ams.pypower.routines.cpf import runcpf # NOQA
ams/pypower/_compat.py ADDED
@@ -0,0 +1,9 @@
1
+
2
+ """
3
+ Compatibility helpers for older Python versions.
4
+
5
+ """
6
+ import sys
7
+
8
+
9
+ PY2 = sys.version_info[0] == 2
@@ -0,0 +1,8 @@
1
+ """
2
+ Module for the core of PYPOWER.
3
+ """
4
+
5
+ from ams.pypower.core.ppoption import ppoption # NOQA
6
+ from ams.pypower.core.pips import pips, pipsver, pipsopf_solver # NOQA
7
+ from ams.pypower.core.ppver import ppver # NOQA
8
+ from ams.pypower.core.solver import ipoptopf_solver # NOQA