Skip to content

Commit aa83d79

Browse files
authored
Update informs list to be consistent with SNOPT 7.7 + updating docstrings for flake8 rst checks (#333)
* updated informs dictionary * doc update * removed old informs * added test for time limit option * fixed flake8 rst issues?
1 parent 52097c6 commit aa83d79

File tree

7 files changed

+26
-30
lines changed

7 files changed

+26
-30
lines changed

doc/advancedFeatures.rst

+7
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ Because the hot start process will store all the previous "restarted" iterations
6262

6363
Time limit (for SNOPT only)
6464
---------------------------
65+
66+
.. note::
67+
68+
Since SNOPT 7.7, the user should rely on the ``Time Limit`` SNOPT option instead of the ``timeLimit`` argument of the ``Optimizer`` instance to set the maximum optimization time.
69+
70+
6571
The :ref:`optimizer` class in pyOptSparse has an attribute used to set the maximum allowable wall time for optimizations using SNOPT.
6672
The code will exit gracefully when such time limit is reached.
6773
This feature is particularly useful when running a time-constrained job, as in the case of most HPC systems.
@@ -79,5 +85,6 @@ Note that the attribute takes the maximum wall time *in seconds* as an integer n
7985
It will NOT interrupt an ongoing function or sensitivity evaluation.
8086
If your function evaluations are expensive, you should be more conservative when setting the ``timeLimit`` option for it to be effective.
8187

88+
8289
.. Clean Optimization Termination
8390
.. ------------------------------

examples/tp109.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Solves Schittkowski's TP109 constraint problem.
33
44
min 3.0*x1+1.*10**(-6)*x1**3+0.522074*10**(-6)*x2**3+2.0*x2
5+
56
s.t. -(x4-x3+0.550) <= 0
67
-(x3-x4+0.550) <= 0
78
-(2.25*10**(+6)-x1**2-x8**2) <= 0
@@ -16,6 +17,7 @@
1617
-0.55 <= xi <= 0.55, i = 3,4
1718
196.0 <= xi <= 252.0, i = 5,6,7
1819
-400.0 <= xi <= 800.0, i = 8,9
20+
1921
where a = 50.176
2022
b = np.sin(0.25)
2123
c = np.cos(0.25)

pyoptsparse/pyOpt_optimization.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,8 @@ def processObjtoDict(self, fobj_in: NumpyType, scaled: bool = True) -> Dict1DTyp
11971197
def processContoVec(
11981198
self, fcon_in: Dict1DType, scaled: bool = True, dtype: str = "d", natural: bool = False
11991199
) -> ndarray:
1200-
"""
1200+
"""A function that converts a dictionary of constraints into a vector
1201+
12011202
Parameters
12021203
----------
12031204
fcon_in : dict
@@ -1267,7 +1268,8 @@ def processContoVec(
12671268
def processContoDict(
12681269
self, fcon_in: ndarray, scaled: bool = True, dtype: str = "d", natural: bool = False, multipliers: bool = False
12691270
) -> Dict1DType:
1270-
"""
1271+
"""A function that converts an array of constraints into a dictionary
1272+
12711273
Parameters
12721274
----------
12731275
fcon_in : array

pyoptsparse/pyOpt_optimizer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -941,7 +941,7 @@ def OPT(optName, *args, **kwargs):
941941
Either a string identifying the optimizer to create, e.g. "SNOPT", or
942942
an enum accessed via ``pyoptsparse.Optimizers``, e.g. ``Optimizers.SNOPT``.
943943
944-
*args, **kwargs : varies
944+
\*args, \*\*kwargs : varies
945945
Passed to optimizer creation.
946946
947947
Returns

pyoptsparse/pySNOPT/pySNOPT.py

+8-27
Original file line numberDiff line numberDiff line change
@@ -116,45 +116,45 @@ def _getDefaultOptions() -> Dict[str, Any]:
116116

117117
@staticmethod
118118
def _getInforms() -> Dict[int, str]:
119+
# INFO exit codes for SNOPT 7.7
119120
informs = {
120121
0: "finished successfully",
121122
1: "optimality conditions satisfied",
122123
2: "feasible point found",
123124
3: "requested accuracy could not be achieved",
124-
4: "weak QP minimizer",
125+
5: "elastic objective minimized",
126+
6: "elastic infeasibilities minimized",
125127
10: "the problem appears to be infeasible",
126128
11: "infeasible linear constraints",
127129
12: "infeasible linear equalities",
128130
13: "nonlinear infeasibilities minimized",
129131
14: "infeasibilities minimized",
130132
15: "infeasible linear constraints in QP subproblem",
133+
16: "infeasible nonelastic constraints",
131134
20: "the problem appears to be unbounded",
132135
21: "unbounded objective",
133136
22: "constraint violation limit reached",
134137
30: "resource limit error",
135138
31: "iteration limit reached",
136139
32: "major iteration limit reached",
137140
33: "the superbasics limit is too small",
141+
34: "time limit reached",
138142
40: "terminated after numerical difficulties",
139143
41: "current point cannot be improved",
140144
42: "singular basis",
141145
43: "cannot satisfy the general constraints",
142146
44: "ill-conditioned null-space basis",
147+
45: "unable to compute acceptable LU factors",
143148
50: "error in the user-supplied functions",
144149
51: "incorrect objective derivatives",
145150
52: "incorrect constraint derivatives",
146-
53: "the QP Hessian is indefinite",
147-
54: "incorrect second derivatives",
148-
55: "incorrect derivatives",
149151
56: "irregular or badly scaled problem functions",
150152
60: "undefined user-supplied functions",
151153
61: "undefined function at the first feasible point",
152154
62: "undefined function at the initial point",
153155
63: "unable to proceed into undefined region",
154156
70: "user requested termination",
155157
71: "terminated during function evaluation",
156-
72: "terminated during constraint evaluation",
157-
73: "terminated during objective evaluation",
158158
74: "terminated from monitor routine",
159159
80: "insufficient storage allocated",
160160
81: "work arrays must have at least 500 elements",
@@ -164,30 +164,11 @@ def _getInforms() -> Dict[int, str]:
164164
90: "input arguments out of range",
165165
91: "invalid input argument",
166166
92: "basis file dimensions do not match this problem",
167-
93: "the QP Hessian is indefinite",
168-
100: "finished successfully",
169-
101: "SPECS file read",
170-
102: "Jacobian structure estimated",
171-
103: "MPS file read",
172-
104: "memory requirements estimated",
173-
105: "user-supplied derivatives appear to be correct",
174-
106: "no derivatives were checked",
175-
107: "some SPECS keywords were not recognized",
176-
110: "errors while processing MPS data",
177-
111: "no MPS file specified",
178-
112: "problem-size estimates too small",
179-
113: "fatal error in the MPS file",
180-
120: "errors while estimating Jacobian structure",
181-
121: "cannot find Jacobian structure at given point",
182-
130: "fatal errors while reading the SP",
183-
131: "no SPECS file (iSpecs le 0 or iSpecs gt 99)",
184-
132: "End-of-file while looking for a BEGIN",
185-
133: "End-of-file while reading SPECS file",
186-
134: "ENDRUN found before any valid SPECS",
187167
140: "system error",
188168
141: "wrong no of basic variables",
189169
142: "error in basis package",
190170
}
171+
191172
return informs
192173

193174
def __call__(
@@ -256,7 +237,7 @@ def __call__(
256237
Specify the maximum amount of time for optimizer to run.
257238
Must be in seconds. This can be useful on queue systems when
258239
you want an optimization to cleanly finish before the
259-
job runs out of time.
240+
job runs out of time. From SNOPT 7.7, use the "Time limit" option instead.
260241
261242
restartDict : dict
262243
A dictionary containing the necessary information for hot-starting SNOPT.

tests/test_hs071.py

+2
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ def test_snopt_informs(self):
173173
self.setup_optProb()
174174
sol = self.optimize(optOptions={"Major iterations limit": 1})
175175
self.assert_inform_equal(sol, 32)
176+
sol = self.optimize(optOptions={"Time Limit": 0.001})
177+
self.assert_inform_equal(sol, 34)
176178

177179
def test_slsqp_informs(self):
178180
self.optName = "SLSQP"

tests/test_tp109.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
Test uses Schittkowski's TP109 constraint problem.
33
44
min 3.0*x1+1.*10**(-6)*x1**3+0.522074*10**(-6)*x2**3+2.0*x2
5+
56
s.t. -(x4-x3+0.550) <= 0
67
-(x3-x4+0.550) <= 0
78
-(2.25*10**(+6)-x1**2-x8**2) <= 0
@@ -16,6 +17,7 @@
1617
-0.55 <= xi <= 0.55, i = 3,4
1718
196.0 <= xi <= 252.0, i = 5,6,7
1819
-400.0 <= xi <= 800.0, i = 8,9
20+
1921
where a = 50.176
2022
b = np.sin(0.25)
2123
c = np.cos(0.25)

0 commit comments

Comments
 (0)