def __init__(self, raiseError=True, options: Dict = {}): """ SNOPT Optimizer Class Initialization """ name = "SNOPT" category = "Local Optimizer" defOpts = self._getDefaultOptions() # these are SNOPT-related options that do not get set via snset self.specialOptions = CaseInsensitiveSet( { "iPrint", "iSumm", "Start", } ) # this is purely within pySNOPT, nothing to do with SNOPT itself self.pythonOptions = CaseInsensitiveSet( { "Save major iteration variables", "Return work arrays", "snSTOP function handle", } ) informs = self._getInforms() if snopt is None: if raiseError: raise Error("There was an error importing the compiled snopt module") else: version = None else: # extract SNOPT version version_str = snopt.sntitle().decode("utf-8") # The version_str is going to look like # S N O P T 7.7.5 (Oct 2020) # we search between "S N O P T" and "(" res = re.search(r"S N O P T(.*)\(", version_str) if res is not None: version = res.group(1).strip() else: version = None super().__init__( name, category, defaultOptions=defOpts, informs=informs, options=options, checkDefaultOptions=False, version=version, ) # SNOPT need Jacobians in csc format self.jacType = "csc" # SNOPT specific Jacobian map self._snopt_jac_map_csr_to_csc: Optional[Tuple[ndarray, ndarray, ndarray]] = None
def test_subsets(self): # test set operations self.assertFalse(self.s2.issubset(self.s)) self.s.update(self.s2) self.assertTrue(self.s2.issubset(self.s)) self.assertFalse({"Option2"}.issubset( self.s)) # set is case sensitive so this should fail self.assertTrue(CaseInsensitiveSet({"Option2"}).issubset( self.s)) # and this should pass
def test_repr_pprint(self): long_set = { "a-longstring", "b-longstring", "c-longstring", "d-longstring", "e-longstring", "f-longstring" } string_format = pformat(CaseInsensitiveSet(long_set)) string_expected = ( "{'a-longstring',\n 'b-longstring',\n 'c-longstring',\n 'd-longstring',\n 'e-longstring',\n 'f-longstring'}" ) self.assertEqual(string_format, string_expected)
def test_bcast(self, class_type): comm = MPI.COMM_WORLD d = {"OPtion1": 1} s = {"OPtion1"} if comm.rank == 0: if class_type == "CaseInsensitiveDict": obj = CaseInsensitiveDict(d) elif class_type == "CaseInsensitiveSet": obj = CaseInsensitiveSet(s) else: obj = None obj = comm.bcast(obj, root=0) self.assertIn("option1", obj)
def __init__(self, raiseError=True, options={}): """ SNOPT Optimizer Class Initialization """ name = "SNOPT" category = "Local Optimizer" self.defOpts = { "iPrint": [int, 18], # Print File Output Unit (override internally in snopt?) "iSumm": [int, 19], # Summary File Output Unit (override internally in snopt?) "Print file": [str, "SNOPT_print.out" ], # Print File Name (specified by subroutine snInit) "Summary file": [str, "SNOPT_summary.out" ], # Summary File Name (specified by subroutine snInit) "Problem Type": [str, ["Minimize", "Maximize", "Feasible point"]], "Start": [ str, ["Cold", "Warm"] ], # used in call to snkerc, the option "Cold Start" etc are NOT allowed "Derivative level": [int, 3], "Proximal iterations limit": [int, 10000 ], # very large # to solve proximal point problem to optimality "Save major iteration variables": [ list, ["step", "merit", "feasibility", "optimality", "penalty"], ], # 'Hessian', 'slack', 'lambda' and 'condZHZ' are also supported } # these are SNOPT-related options that do not get set via snset self.specialOptions = CaseInsensitiveSet({ "iPrint", "iSumm", "Start", }) # this is purely within pySNOPT, nothing to do with SNOPT itself self.pythonOptions = CaseInsensitiveSet( {"Save major iteration variables"}) self.informs = { 0: "finished successfully", 1: "optimality conditions satisfied", 2: "feasible point found", 3: "requested accuracy could not be achieved", 4: "weak QP minimizer", 10: "the problem appears to be infeasible", 11: "infeasible linear constraints", 12: "infeasible linear equalities", 13: "nonlinear infeasibilities minimized", 14: "infeasibilities minimized", 15: "infeasible linear constraints in QP subproblem", 20: "the problem appears to be unbounded", 21: "unbounded objective", 22: "constraint violation limit reached", 30: "resource limit error", 31: "iteration limit reached", 32: "major iteration limit reached", 33: "the superbasics limit is too small", 40: "terminated after numerical difficulties", 41: "current point cannot be improved", 42: "singular basis", 43: "cannot satisfy the general constraints", 44: "ill-conditioned null-space basis", 50: "error in the user-supplied functions", 51: "incorrect objective derivatives", 52: "incorrect constraint derivatives", 53: "the QP Hessian is indefinite", 54: "incorrect second derivatives", 55: "incorrect derivatives", 56: "irregular or badly scaled problem functions", 60: "undefined user-supplied functions", 61: "undefined function at the first feasible point", 62: "undefined function at the initial point", 63: "unable to proceed into undefined region", 70: "user requested termination", 71: "terminated during function evaluation", 72: "terminated during constraint evaluation", 73: "terminated during objective evaluation", 74: "terminated from monitor routine", 80: "insufficient storage allocated", 81: "work arrays must have at least 500 elements", 82: "not enough character storage", 83: "not enough integer storage", 84: "not enough real storage", 90: "input arguments out of range", 91: "invalid input argument", 92: "basis file dimensions do not match this problem", 93: "the QP Hessian is indefinite", 100: "finished successfully", 101: "SPECS file read", 102: "Jacobian structure estimated", 103: "MPS file read", 104: "memory requirements estimated", 105: "user-supplied derivatives appear to be correct", 106: "no derivatives were checked", 107: "some SPECS keywords were not recognized", 110: "errors while processing MPS data", 111: "no MPS file specified", 112: "problem-size estimates too small", 113: "fatal error in the MPS file", 120: "errors while estimating Jacobian structure", 121: "cannot find Jacobian structure at given point", 130: "fatal errors while reading the SP", 131: "no SPECS file (iSpecs le 0 or iSpecs gt 99)", 132: "End-of-file while looking for a BEGIN", 133: "End-of-file while reading SPECS file", 134: "ENDRUN found before any valid SPECS", 140: "system error", 141: "wrong no of basic variables", 142: "error in basis package", } if snopt is None: if raiseError: raise Error( "There was an error importing the compiled snopt module") super().__init__( name, category, defaultOptions=self.defOpts, informs=self.informs, options=options, checkDefaultOptions=False, ) # SNOPT need Jacobians in csc format self.jacType = "csc" # SNOPT specific Jacobian map self._snopt_jac_map_csr_to_csc = None
def test_union(self): s3 = self.s.union(self.s2) self.assertTrue(isinstance(s3, CaseInsensitiveSet)) self.assertEqual(s3, CaseInsensitiveSet({"option1", "option2"}))
def test_invalid_init(self): with self.assertRaises(TypeError): CaseInsensitiveSet({1, 2.5})
def test_empty_init(self): s = CaseInsensitiveSet() self.assertEqual(len(s), 0) self.assertEqual(list(s), [])
def setUp(self): self.s = CaseInsensitiveSet({"Option1"}) self.s2 = CaseInsensitiveSet({"OPTION1", "opTION2"}) self.s3 = {"regular set"}
class TestCaseInsensitiveSet(unittest.TestCase): def setUp(self): self.s = CaseInsensitiveSet({"Option1"}) self.s2 = CaseInsensitiveSet({"OPTION1", "opTION2"}) self.s3 = {"regular set"} def test_empty_init(self): s = CaseInsensitiveSet() self.assertEqual(len(s), 0) self.assertEqual(list(s), []) def test_invalid_init(self): with self.assertRaises(TypeError): CaseInsensitiveSet({1, 2.5}) def test_add_contains(self): # test __contains__ and add() self.assertIn("OPTION1", self.s) # test original capitalization is preserved on initialization self.assertEqual({"Option1"}, self.s.data) self.s.add("OPTION2") self.assertIn("option2", self.s) # now add the same key again with different capitalization self.s.add("option2") self.assertNotIn("option2", self.s.data) self.assertIn("OPTION2", self.s.data) # test original capitalization is preserved on new item self.assertEqual({"Option1", "OPTION2"}, self.s.data) def test_len(self): self.assertEqual(len(self.s2), 2) self.s2.remove("Option2") self.assertEqual(len(self.s2), 1) def test_update(self): self.s.update(self.s2) self.assertTrue(isinstance(self.s, CaseInsensitiveSet)) self.assertEqual(len(self.s), 2) self.assertEqual(self.s.data, {"Option1", "opTION2"}) def test_update_with_regular_set(self): # test regular set update self.s.update(self.s3) self.assertTrue(isinstance(self.s, CaseInsensitiveSet)) self.assertIn("REGULAR SET", self.s) self.assertEqual({"Option1", "regular set"}, self.s.data) def test_update_regular_set_with_set(self): self.s3.update(self.s) self.assertFalse(isinstance(self.s3, CaseInsensitiveSet)) self.assertTrue(isinstance(self.s3, set)) self.assertNotIn("REGULAR SET", self.s3) # s4 is a set and is not case insensitive self.assertIn("regular set", self.s3) # this works self.assertEqual(self.s3, {"Option1", "regular set"}) def test_subsets(self): # test set operations self.assertFalse(self.s2.issubset(self.s)) self.s.update(self.s2) self.assertTrue(self.s2.issubset(self.s)) self.assertFalse({"Option2"}.issubset( self.s)) # set is case sensitive so this should fail self.assertTrue(CaseInsensitiveSet({"Option2"}).issubset( self.s)) # and this should pass def test_union(self): s3 = self.s.union(self.s2) self.assertTrue(isinstance(s3, CaseInsensitiveSet)) self.assertEqual(s3, CaseInsensitiveSet({"option1", "option2"})) # NOTE capitalization is NOT guaranteed since union is transitive! # we only guarantee the entries are there, but for duplicate keys the capitalization can be from either def test_remove(self): # test remove with self.assertRaises(KeyError): self.s2.remove("INVALID") self.s2.remove("option2") self.assertNotIn("OPTION2", self.s2) self.assertEqual(len(self.s2), 1) def test_equal(self): self.assertNotEqual(self.s, self.s2) self.s2.remove("opTION2") self.assertEqual(self.s, self.s2) def test_pickle(self): new_set = pickle.loads(pickle.dumps(self.s)) self.assertEqual(self.s, new_set) def test_iter(self): res = set() for k in self.s2: res.add(k) self.assertEqual(res, self.s2) def test_repr(self): self.assertEqual(self.s2.__str__(), self.s2.data.__str__()) def test_repr_pprint(self): long_set = { "a-longstring", "b-longstring", "c-longstring", "d-longstring", "e-longstring", "f-longstring" } string_format = pformat(CaseInsensitiveSet(long_set)) string_expected = ( "{'a-longstring',\n 'b-longstring',\n 'c-longstring',\n 'd-longstring',\n 'e-longstring',\n 'f-longstring'}" ) self.assertEqual(string_format, string_expected)
def test_set(self): # test __contains__ and add() s = CaseInsensitiveSet({"Option1"}) self.assertIn("OPTION1", s) s.add("OPTION2") self.assertIn("option2", s) # test update() s2 = CaseInsensitiveSet({"OPTION2", "opTION3"}) s.update(s2) self.assertEqual(len(s), 3) # test set operations self.assertTrue(s2.issubset(s)) self.assertFalse({ "Option2" }.issubset(s)) # set is case sensitive so this should fail self.assertTrue(CaseInsensitiveSet( {"Option2"}).issubset(s)) # and this should pass # test remove s.remove("option3") self.assertNotIn("OPTION3", s) self.assertEqual(len(s), 2) s3 = s.union(s2) self.assertEqual(s3, CaseInsensitiveSet({"option1", "option2", "option3"}))
class TestCaseInsensitiveSet(unittest.TestCase): def setUp(self): self.s = CaseInsensitiveSet({"Option1"}) self.s2 = CaseInsensitiveSet({"OPTION1", "opTION2"}) self.s3 = {"regular set"} def test_add_contains(self): # test __contains__ and add() self.assertIn("OPTION1", self.s) # test original capitalization is preserved on initialization self.assertEqual({"Option1"}, self.s._getKeys()) self.s.add("OPTION2") self.assertIn("option2", self.s) # now add the same key again with different capitalization self.s.add("option2") self.assertNotIn("option2", self.s._getKeys()) self.assertIn("OPTION2", self.s._getKeys()) # test original capitalization is preserved on new item self.assertEqual({"Option1", "OPTION2"}, self.s._getKeys()) def test_len(self): self.assertEqual(len(self.s2), 2) self.s2.remove("Option2") self.assertEqual(len(self.s2), 1) def test_update(self): # test update() self.s.update(self.s2) self.assertTrue(isinstance(self.s, CaseInsensitiveSet)) self.assertEqual(len(self.s), 2) self.assertEqual(self.s._getKeys(), {"Option1", "opTION2"}) def test_update_with_regular_set(self): # test regular set update self.s.update(self.s3) self.assertTrue(isinstance(self.s, CaseInsensitiveSet)) self.assertIn("REGULAR SET", self.s) self.assertEqual({"Option1", "regular set"}, self.s._getKeys()) def test_update_regular_set_with_set(self): self.s3.update(self.s) self.assertFalse(isinstance(self.s3, CaseInsensitiveSet)) self.assertTrue(isinstance(self.s3, set)) self.assertNotIn("REGULAR SET", self.s3) # s4 is a set and is not case insensitive self.assertIn("regular set", self.s3) # this works self.assertEqual(self.s3, {"Option1", "regular set"}) def test_subsets(self): # test set operations self.assertFalse(self.s2.issubset(self.s)) self.s.update(self.s2) self.assertTrue(self.s2.issubset(self.s)) self.assertFalse({"Option2"}.issubset( self.s)) # set is case sensitive so this should fail self.assertTrue(CaseInsensitiveSet({"Option2"}).issubset( self.s)) # and this should pass def test_union(self): s3 = self.s.union(self.s2) self.assertTrue(isinstance(s3, CaseInsensitiveSet)) self.assertEqual(s3, CaseInsensitiveSet({"option1", "option2"})) # NOTE capitalization is NOT guaranteed since union is transitive! # we only guarantee the entries are there, but for duplicate keys the capitalization can be from either def test_remove(self): # test remove with self.assertRaises(KeyError): self.s2.remove("INVALID") self.s2.remove("option2") self.assertNotIn("OPTION2", self.s2) self.assertEqual(len(self.s2), 1) def test_equal(self): self.assertNotEqual(self.s, self.s2) self.s2.remove("opTION2") self.assertEqual(self.s, self.s2)