Skip to content

Commit

Permalink
Bugfix for optimal objective value (#364)
Browse files Browse the repository at this point in the history
* set objectives.value to fStar

* add test

* Update testing_utils.py

* addressed comment
  • Loading branch information
ewu63 authored Dec 4, 2023
1 parent f56e159 commit 75e6479
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 9 deletions.
12 changes: 10 additions & 2 deletions pyoptsparse/pyOpt_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, optProb, xStar, fStar, lambdaStar, optInform, info):
in the Solution object.
"""

Optimization.__init__(self, optProb.name, None)
super().__init__(optProb.name, None)

# Copy over the variables, constraints, and objectives
self.variables = copy.deepcopy(optProb.variables)
Expand All @@ -43,11 +43,19 @@ def __init__(self, optProb, xStar, fStar, lambdaStar, optInform, info):
xopt = optProb._mapXtoOpt(optProb.processXtoVec(xStar))
# Now set the x-values:
i = 0
for dvGroup in self.variables:
for dvGroup in self.variables.keys():
for var in self.variables[dvGroup]:
var.value = xopt[i]
i += 1

# Now set the f-values
if isinstance(fStar, float) or len(fStar) == 1:
self.objectives[list(self.objectives.keys())[0]].value = float(fStar)
fStar = float(fStar)
else:
for f_name, f in self.objectives.items():
f.value = fStar[f_name]

self.optTime = info["optTime"]
self.userObjTime = info["userObjTime"]
self.userSensTime = info["userSensTime"]
Expand Down
11 changes: 4 additions & 7 deletions tests/testing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from baseclasses.testing.assertions import assert_dict_allclose, assert_equal
import numpy as np
from numpy.testing import assert_allclose
from pkg_resources import parse_version

# First party modules
from pyoptsparse import OPT, History
Expand Down Expand Up @@ -121,16 +120,14 @@ def assert_solution_allclose(self, sol, tol, partial_x=False):
self.sol_index = 0
# now we assert against the closest solution
# objective
# sol.fStar was broken for earlier versions of SNOPT
if self.optName == "SNOPT" and parse_version(self.optVersion) < parse_version("7.7.7"):
sol_objectives = np.array([sol.objectives[key].value for key in sol.objectives])
else:
sol_objectives = sol.fStar
assert_allclose(sol_objectives, self.fStar[self.sol_index], atol=tol, rtol=tol)
assert_allclose(sol.fStar, self.fStar[self.sol_index], atol=tol, rtol=tol)
# make sure fStar and sol.objectives values match
assert_allclose(sol.fStar, [obj.value for obj in sol.objectives.values()], rtol=1e-12)
# x
assert_dict_allclose(sol.xStar, self.xStar[self.sol_index], atol=tol, rtol=tol, partial=partial_x)
dv = sol.getDVs()
assert_dict_allclose(dv, self.xStar[self.sol_index], atol=tol, rtol=tol, partial=partial_x)
assert_dict_allclose(sol.xStar, dv, rtol=1e-12)
# lambda
if (
hasattr(self, "lambdaStar")
Expand Down

0 comments on commit 75e6479

Please sign in to comment.