|
11 | 11 |
|
12 | 12 | import pyomo.common.unittest as unittest |
13 | 13 | import pyomo.environ as pyo |
14 | | -from pyomo.contrib.fbbt.fbbt import fbbt, compute_bounds_on_expr |
| 14 | +from pyomo.contrib.fbbt.fbbt import fbbt, compute_bounds_on_expr, _before_child_handlers |
15 | 15 | from pyomo.common.dependencies import numpy as np, numpy_available |
16 | 16 | from pyomo.common.fileutils import find_library |
17 | 17 | from pyomo.common.log import LoggingIntercept |
@@ -1363,3 +1363,30 @@ def test_ranged_expression(self): |
1363 | 1363 | self.assertEqual(m.l.bounds, (2, 7)) |
1364 | 1364 | self.assertEqual(m.x.bounds, (3, 7)) |
1365 | 1365 | self.assertEqual(m.u.bounds, (3, 8)) |
| 1366 | + |
| 1367 | + @unittest.skipUnless(numpy_available, "Test requires numpy") |
| 1368 | + def test_numpy_leaves(self): |
| 1369 | + m = pyo.ConcreteModel() |
| 1370 | + m.l = pyo.Var(bounds=(2, None)) |
| 1371 | + m.x = pyo.Var() |
| 1372 | + m.u = pyo.Var(bounds=(None, 8)) |
| 1373 | + m.c = pyo.Constraint( |
| 1374 | + expr=pyo.inequality(m.l + np.int32(1), m.x, m.u - np.float64(1)) |
| 1375 | + ) |
| 1376 | + |
| 1377 | + # Remove the numpy types so we can test that automatic numeric |
| 1378 | + # type registrations |
| 1379 | + old = [(t, _before_child_handlers.pop(t, None)) for t in (np.int32, np.float64)] |
| 1380 | + |
| 1381 | + try: |
| 1382 | + self.tightener(m) |
| 1383 | + self.tightener(m) |
| 1384 | + self.assertEqual(m.l.bounds, (2, 6.0)) |
| 1385 | + self.assertEqual(m.x.bounds, (3, 7.0)) |
| 1386 | + self.assertEqual(m.u.bounds, (4, 8.0)) |
| 1387 | + finally: |
| 1388 | + for t, fcn in old: |
| 1389 | + if fcn is None: |
| 1390 | + _before_child_handlers.pop(t, None) |
| 1391 | + else: |
| 1392 | + _before_child_handlers[t] = fcn |
0 commit comments