Summary
pyomo.contrib.fbbt.fbbt() emits a NumPy RuntimeWarning when a variable has NumPy scalar bounds and FBBT reaches interval multiplication patterns that include expected 0 * inf products.
With equivalent native Python float bounds, the same model is quiet.
This appears to be warning hygiene in FBBT interval arithmetic, not an infeasibility in the downstream model: interval.mul() already checks for nan and returns (-inf, inf), but the eager tuple construction evaluates products such as 0 * inf first. If one operand is a NumPy scalar, NumPy emits RuntimeWarning: invalid value encountered in scalar multiply before Pyomo's nan handling runs.
Minimal working example
import warnings
import numpy as np
import pyomo.environ as pyo
from pyomo.contrib.fbbt.fbbt import fbbt
def run_case(bound_type):
m = pyo.ConcreteModel()
m.x = pyo.Var(bounds=(bound_type(0), bound_type(1)))
m.y = pyo.Var(bounds=(bound_type(0), bound_type(1)))
m.c = pyo.Constraint(expr=m.x * m.y == 0)
with warnings.catch_warnings(record=True) as records:
warnings.simplefilter("always", RuntimeWarning)
fbbt(m.c)
print(bound_type, len(records), [str(r.message) for r in records])
run_case(float)
run_case(np.float64)
Observed output:
<class 'float'> 0 []
<class 'numpy.float64'> 2 ['invalid value encountered in scalar multiply', 'invalid value encountered in scalar multiply']
Expected behavior
FBBT should not emit a RuntimeWarning for equivalent NumPy scalar bounds. It should either handle the nan case quietly, as it already intends to do, or coerce interval endpoints to native numeric types before multiplication.
Downstream context
This surfaced while working on the GDPLib HDA benchmark refactor:
The warning appeared during GDPopt preprocessing/FBBT on HDA flash constraints. A local diagnostic showed that coercing HDA variable bounds and initial values from pandas/NumPy scalars to native Python floats dropped the FBBT runtime warnings from 9 to 0, without changing the algebra.
The promoted-warning traceback reaches:
pyomo/contrib/gdpopt/solve_subproblem.py -> fbbt(...)
pyomo/contrib/fbbt/fbbt.py -> _prop_bnds_root_to_leaf_ProductExpression
pyomo/contrib/fbbt/interval.py -> div(...)
pyomo/contrib/fbbt/interval.py -> mul(...)
RuntimeWarning: invalid value encountered in scalar multiply
Environment
Python 3.12.13
Pyomo 6.10.0
NumPy 2.4.3
I also checked Pyomo/pyomo@main; pyomo/contrib/fbbt/interval.py::mul still appears to use the same eager product tuple:
for i in (xl * yl, xu * yu, xu * yl, xl * yu):
...
Summary
pyomo.contrib.fbbt.fbbt()emits a NumPyRuntimeWarningwhen a variable has NumPy scalar bounds and FBBT reaches interval multiplication patterns that include expected0 * infproducts.With equivalent native Python
floatbounds, the same model is quiet.This appears to be warning hygiene in FBBT interval arithmetic, not an infeasibility in the downstream model:
interval.mul()already checks fornanand returns(-inf, inf), but the eager tuple construction evaluates products such as0 * inffirst. If one operand is a NumPy scalar, NumPy emitsRuntimeWarning: invalid value encountered in scalar multiplybefore Pyomo'snanhandling runs.Minimal working example
Observed output:
Expected behavior
FBBT should not emit a
RuntimeWarningfor equivalent NumPy scalar bounds. It should either handle thenancase quietly, as it already intends to do, or coerce interval endpoints to native numeric types before multiplication.Downstream context
This surfaced while working on the GDPLib HDA benchmark refactor:
hdato fix benchmark issues SECQUOIA/gdplib#67The warning appeared during GDPopt preprocessing/FBBT on HDA flash constraints. A local diagnostic showed that coercing HDA variable bounds and initial values from pandas/NumPy scalars to native Python floats dropped the FBBT runtime warnings from 9 to 0, without changing the algebra.
The promoted-warning traceback reaches:
Environment
I also checked
Pyomo/pyomo@main;pyomo/contrib/fbbt/interval.py::mulstill appears to use the same eager product tuple: