From 4ed7ce953eed8a1955e51dc2ab5b4e7a2806df05 Mon Sep 17 00:00:00 2001 From: Ella Wu <602725+ewu63@users.noreply.github.com> Date: Wed, 8 May 2024 18:54:21 -0400 Subject: [PATCH] Fix empty hist (#399) * add failing test * fix reshaping * version bump * add __all__ --- pyoptsparse/__init__.py | 24 +++++++++++++++++++++++- pyoptsparse/pyOpt_history.py | 5 ++++- tests/test_hs015.py | 16 ++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/pyoptsparse/__init__.py b/pyoptsparse/__init__.py index 365985b2..903a0881 100644 --- a/pyoptsparse/__init__.py +++ b/pyoptsparse/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.11.0" +__version__ = "2.11.1" from .pyOpt_history import History from .pyOpt_variable import Variable @@ -19,3 +19,25 @@ from .pyNSGA2.pyNSGA2 import NSGA2 from .pyALPSO.pyALPSO import ALPSO from .pyParOpt.ParOpt import ParOpt + +__all__ = [ + "History", + "Variable", + "Gradient", + "Constraint", + "Objective", + "Optimization", + "Optimizer", + "OPT", + "Optimizers", + "Solution", + "SNOPT", + "IPOPT", + "SLSQP", + "CONMIN", + "PSQP", + "NLPQLP", + "NSGA2", + "ALPSO", + "ParOpt", +] diff --git a/pyoptsparse/pyOpt_history.py b/pyoptsparse/pyOpt_history.py index b204f192..efc31dd7 100644 --- a/pyoptsparse/pyOpt_history.py +++ b/pyoptsparse/pyOpt_history.py @@ -651,7 +651,10 @@ def getValues(self, names=None, callCounters=None, major=True, scale=False, stac # reshape lists into numpy arrays for name in names: # we just stack along axis 0 - data[name] = np.stack(data[name], axis=0) + if len(data[name]) > 0: + data[name] = np.stack(data[name], axis=0) + else: + data[name] = np.array(data[name]) # we cast 1D arrays to 2D, for scalar values if data[name].ndim == 1: data[name] = np.expand_dims(data[name], 1) diff --git a/tests/test_hs015.py b/tests/test_hs015.py index a7870044..88f8779c 100644 --- a/tests/test_hs015.py +++ b/tests/test_hs015.py @@ -193,6 +193,22 @@ def test_snopt_snstop(self): # we should get 70/74 self.assert_inform_equal(sol, optInform=74) + def test_snopt_failed_initial(self): + def failed_fun(x_dict): + funcs = {"obj": 0.0, "con": [np.nan, np.nan]} + fail = True + return funcs, fail + + self.optName = "SNOPT" + self.setup_optProb() + # swap obj to report NaN + self.optProb.objFun = failed_fun + sol = self.optimize(optOptions={}, storeHistory=True) + self.assert_inform_equal(sol, optInform=61) + # make sure empty history does not error out + hist = History(self.histFileName, flag="r") + hist.getValues() + if __name__ == "__main__": unittest.main()