Skip to content

Commit

Permalink
Merge branch 'main' into config-default
Browse files Browse the repository at this point in the history
  • Loading branch information
jsiirola committed Oct 31, 2024
2 parents 9961893 + dde27f1 commit 1107f0c
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 53 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion doc/OnlineDocs/howto/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ How-To Guides
solver_recipes
abstract_models/index.rst
debugging
contribution_guide
../contribution_guide
2 changes: 1 addition & 1 deletion doc/OnlineDocs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Contributing to Pyomo
---------------------

Interested in contributing code or documentation to the project? Check out our
:doc:`Contribution Guide <howto/contribution_guide>`
:doc:`Contribution Guide <contribution_guide>`

Related Packages
----------------
Expand Down
6 changes: 3 additions & 3 deletions pyomo/contrib/doe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
deprecation_message = (
"Pyomo.DoE has been refactored. The current interface utilizes Experiment "
"objects that label unknown parameters, experiment inputs, experiment outputs "
"and measurement error. This avoids string-based naming which is fragile. For "
"instructions to use the new interface, please see the Pyomo.DoE under the contributed "
"packages documentation at `https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`"
"and measurement error. This avoids fragile string-based naming. For "
"instructions on using the new interface, please see the Pyomo.DoE documentation "
"`https://pyomo.readthedocs.io/en/latest/explanation/analysis/doe/doe.html`"
)


Expand Down
12 changes: 8 additions & 4 deletions pyomo/repn/ampl.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ def _strip_template_comments(vars_, base_):
vars_[k] = '\n'.join(v_lines)


def _inv2str(val):
return f"{val._str() if hasattr(val, '_str') else val}"


# The "standard" text mode template is the debugging template with the
# comments removed
class TextNLTemplate(TextNLDebugTemplate):
Expand Down Expand Up @@ -542,7 +546,7 @@ def handle_product_node(visitor, node, arg1, arg2):
_prod = mult * arg2[1]
if _prod:
deprecation_warning(
f"Encountered {mult}*{str(arg2[1])} in expression tree. "
f"Encountered {mult}*{_inv2str(arg2[1])} in expression tree. "
"Mapping the NaN result to 0 for compatibility "
"with the nl_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -571,7 +575,7 @@ def handle_product_node(visitor, node, arg1, arg2):
_prod = mult * arg2[1]
if _prod:
deprecation_warning(
f"Encountered {str(mult)}*{arg2[1]} in expression tree. "
f"Encountered {_inv2str(mult)}*{arg2[1]} in expression tree. "
"Mapping the NaN result to 0 for compatibility "
"with the nl_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -979,7 +983,7 @@ def _before_monomial(visitor, child):
arg2 = visitor.fixed_vars[_id]
if arg2 != arg2:
deprecation_warning(
f"Encountered {arg1}*{arg2} in expression tree. "
f"Encountered {arg1}*{_inv2str(arg2)} in expression tree. "
"Mapping the NaN result to 0 for compatibility "
"with the nl_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -1019,7 +1023,7 @@ def _before_linear(visitor, child):
arg2 = visitor.check_constant(arg2.value, arg2)
if arg2 != arg2:
deprecation_warning(
f"Encountered {arg1}*{str(arg2.value)} in expression "
f"Encountered {arg1}*{_inv2str(arg2)} in expression "
"tree. Mapping the NaN result to 0 for compatibility "
"with the nl_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down
14 changes: 10 additions & 4 deletions pyomo/repn/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@
_GENERAL = ExprType.GENERAL


def _inv2str(val):
return f"{val._str() if hasattr(val, '_str') else val}"


def _merge_dict(dest_dict, mult, src_dict):
if mult == 1:
for vid, coef in src_dict.items():
Expand Down Expand Up @@ -211,8 +215,10 @@ def _handle_product_constant_constant(visitor, node, arg1, arg2):
ans = arg1[1] * arg2[1]
if ans != ans:
if not arg1[1] or not arg2[1]:
a = _inv2str(arg1[1])
b = _inv2str(arg2[1])
deprecation_warning(
f"Encountered {str(arg1[1])}*{str(arg2[1])} in expression tree. "
f"Encountered {a}*{b} in expression tree. "
"Mapping the NaN result to 0 for compatibility "
"with the lp_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -580,7 +586,7 @@ def _before_monomial(visitor, child):
arg2 = visitor.check_constant(arg2.value, arg2)
if arg2 != arg2:
deprecation_warning(
f"Encountered {arg1}*{str(arg2.value)} in expression "
f"Encountered {arg1}*{_inv2str(arg2)} in expression "
"tree. Mapping the NaN result to 0 for compatibility "
"with the lp_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -613,7 +619,7 @@ def _before_linear(visitor, child):
arg2 = visitor.check_constant(arg2.value, arg2)
if arg2 != arg2:
deprecation_warning(
f"Encountered {arg1}*{str(arg2.value)} in expression "
f"Encountered {arg1}*{_inv2str(arg2)} in expression "
"tree. Mapping the NaN result to 0 for compatibility "
"with the lp_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down Expand Up @@ -799,7 +805,7 @@ def finalizeResult(self, result):
c != c for c in ans.linear.values()
):
deprecation_warning(
f"Encountered {str(mult)}*nan in expression tree. "
f"Encountered {mult}*nan in expression tree. "
"Mapping the NaN result to 0 for compatibility "
"with the lp_v1 writer. In the future, this NaN "
"will be preserved/emitted to comply with IEEE-754.",
Expand Down
22 changes: 11 additions & 11 deletions pyomo/repn/tests/ampl/test_nlv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
)
import pyomo.environ as pyo

_invalid_1j = r'InvalidNumber\((\([-+0-9.e]+\+)?1j\)?\)'
nan = float('nan')


class INFO(object):
Expand Down Expand Up @@ -171,7 +171,7 @@ def test_errors_divide_by_0(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -186,7 +186,7 @@ def test_errors_divide_by_0(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -201,7 +201,7 @@ def test_errors_divide_by_0(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -216,7 +216,7 @@ def test_errors_divide_by_0(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -231,7 +231,7 @@ def test_errors_divide_by_0(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -424,7 +424,7 @@ def test_errors_negative_frac_pow(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertRegex(str(repn.const), _invalid_1j)
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(1j))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -440,7 +440,7 @@ def test_errors_negative_frac_pow(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertRegex(str(repn.const), _invalid_1j)
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(1j))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -460,7 +460,7 @@ def test_errors_unary_func(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -484,7 +484,7 @@ def test_errors_propagate_nan(self):
)
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -494,7 +494,7 @@ def test_errors_propagate_nan(self):
repn = info.visitor.walk_expression((expr, None, None, 1))
self.assertEqual(repn.nl, None)
self.assertEqual(repn.mult, 1)
self.assertEqual(str(repn.const), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.const, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down
36 changes: 19 additions & 17 deletions pyomo/repn/tests/test_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def test_scalars(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -216,7 +216,7 @@ def test_scalars(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -227,7 +227,7 @@ def test_scalars(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(1j)')
self.assertEqual(repn.constant, InvalidNumber(1j))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -266,7 +266,7 @@ def test_npv(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -501,7 +501,7 @@ def test_monomial(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -511,7 +511,7 @@ def test_monomial(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand All @@ -521,7 +521,7 @@ def test_monomial(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -564,7 +564,7 @@ def test_monomial(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -778,7 +778,8 @@ def test_linear(self):
with LoggingIntercept() as LOG:
repn = LinearRepnVisitor(**cfg).walk_expression(e)
self.assertIn(
"DEPRECATED: Encountered 0*nan in expression tree.", LOG.getvalue()
"DEPRECATED: Encountered 0*InvalidNumber(nan) in expression tree.",
LOG.getvalue(),
)

self.assertEqual(cfg.subexpr, {})
Expand Down Expand Up @@ -1460,9 +1461,8 @@ def test_errors_propagate_nan(self):
"\texpression: (x + 1)/p\n",
)
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertEqual(len(repn.linear), 1)
self.assertEqual(str(repn.linear[id(m.x)]), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertStructuredAlmostEqual(repn.linear, {id(m.x): InvalidNumber(nan)})
self.assertEqual(repn.nonlinear, None)

expr = m.y + m.x + m.z + ((3 * m.x) / m.p) / m.y
Expand All @@ -1477,16 +1477,16 @@ def test_errors_propagate_nan(self):
)
self.assertEqual(repn.multiplier, 1)
self.assertEqual(repn.constant, 1)
self.assertEqual(len(repn.linear), 2)
self.assertEqual(repn.linear[id(m.z)], 1)
self.assertEqual(str(repn.linear[id(m.x)]), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(
repn.linear, {id(m.z): 1, id(m.x): InvalidNumber(nan)}
)
self.assertEqual(repn.nonlinear, None)

m.y.fix(None)
expr = log(m.y) + 3
repn = LinearRepnVisitor(**cfg).walk_expression(expr)
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(nan)')
self.assertStructuredAlmostEqual(repn.constant, InvalidNumber(nan))
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down Expand Up @@ -1644,7 +1644,9 @@ def test_nonnumeric(self):
self.assertEqual(cfg.var_map, {})
self.assertEqual(cfg.var_order, {})
self.assertEqual(repn.multiplier, 1)
self.assertEqual(str(repn.constant), 'InvalidNumber(array([3, 4]))')
self.assertStructuredAlmostEqual(
repn.constant, InvalidNumber(numpy.array([3, 4]))
)
self.assertEqual(repn.linear, {})
self.assertEqual(repn.nonlinear, None)

Expand Down
4 changes: 2 additions & 2 deletions pyomo/repn/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ def test_apply_operation(self):
pyomo.repn.util.HALT_ON_EVALUATION_ERROR = False
with LoggingIntercept() as LOG:
val = apply_node_operation(div, [1, 0])
self.assertEqual(str(val), "InvalidNumber(nan)")
self.assertStructuredAlmostEqual(val, InvalidNumber(float('nan')))
self.assertEqual(
LOG.getvalue(),
"Exception encountered evaluating expression 'div(1, 0)'\n"
Expand Down Expand Up @@ -293,7 +293,7 @@ class Visitor(object):
pyomo.repn.util.HALT_ON_EVALUATION_ERROR = False
with LoggingIntercept() as LOG:
val = complex_number_error(1j, visitor, exp)
self.assertEqual(str(val), "InvalidNumber(1j)")
self.assertEqual(val, InvalidNumber(1j))
self.assertEqual(
LOG.getvalue(),
"Complex number returned from expression\n"
Expand Down
Loading

0 comments on commit 1107f0c

Please sign in to comment.