Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

calc_variable_from_constraint: guard against expression overflow #3541

Merged
merged 2 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions pyomo/util/calc_var_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ def calculate_variable_from_constraint(
intercept = (residual_1 - upper) - slope * x1
if slope:
variable.set_value(-intercept / slope, skip_validation=True)
body_val = value(body, exception=False)
try:
body_val = value(body, exception=False)
except OverflowError:
body_val = None
if body_val.__class__ not in _invalid_types and abs(body_val - upper) < eps:
# Re-set the variable value to trigger any warnings WRT
# the final variable state
Expand Down Expand Up @@ -277,18 +280,25 @@ def calculate_variable_from_constraint(
while alpha > alpha_min:
# check if the value at xkp1 has sufficient reduction in
# the residual
fkp1 = value(expr, exception=False)
# HACK for Python3 support, pending resolution of #879
# Issue #879 also pertains to other checks for "complex"
# in this method.
if fkp1.__class__ in _invalid_types:
# We cannot perform computations on complex numbers
fkp1 = None
if fkp1 is not None and fkp1**2 < c1 * fk**2:
# found an alpha value with sufficient reduction
# continue to the next step
fk = fkp1
break
try:
fkp1 = value(expr, exception=False)
# HACK for Python3 support, pending resolution of #879
# Issue #879 also pertains to other checks for "complex"
# in this method.
if fkp1.__class__ in _invalid_types:
# We cannot perform computations on complex numbers
fkp1 = None
if fkp1 is not None and fkp1**2 < c1 * fk**2:
# found an alpha value with sufficient reduction
# continue to the next step
fk = fkp1
break
except OverflowError:
# Encountered an overflow, either from evaluating
# this point in the line search (to get fkp1) or
# from squaring fkp1. (The example from #3540
# actually triggers both). Reject this alpha value.
pass
alpha /= 2.0
xkp1 = xk + alpha * pk
variable.set_value(xkp1, skip_validation=True)
Expand Down
10 changes: 10 additions & 0 deletions pyomo/util/tests/test_calc_var_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,13 @@ def test_external_function_explicit_sympy(self):
calculate_variable_from_constraint(
m.x, m.c, diff_mode=differentiate.Modes.sympy
)

def test_linea_search_overflow(self):
# This tests the example from #3540
m = ConcreteModel()
m.x = Var(initialize=5)
m.y = Var(initialize=1)
m.con = Constraint(expr=m.y == 10 ** (-m.x))

calculate_variable_from_constraint(m.x, m.con)
self.assertAlmostEqual(value(m.x), 0)
Loading