Skip to content

Commit b7b0ac7

Browse files
committed
fix for float rounding causing negative
1 parent 7aa5ce3 commit b7b0ac7

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

ngraph/results/flow.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def __post_init__(self) -> None:
6868
)
6969
raise TypeError("FlowEntry.priority must be a non-negative int")
7070

71+
# Basic numeric validation
7172
for name, value in (
7273
("demand", self.demand),
7374
("placed", self.placed),
@@ -79,9 +80,25 @@ def __post_init__(self) -> None:
7980
if not math.isfinite(float(value)):
8081
logger.error("FlowEntry.%s must be finite: %r", name, value)
8182
raise ValueError(f"FlowEntry.{name} must be finite")
82-
if float(value) < 0.0:
83-
logger.error("FlowEntry.%s must be non-negative: %r", name, value)
84-
raise ValueError(f"FlowEntry.{name} must be non-negative")
83+
84+
# Non-negativity with tolerance for floating-point artifacts on 'dropped'
85+
if float(self.demand) < 0.0:
86+
logger.error("FlowEntry.demand must be non-negative: %r", self.demand)
87+
raise ValueError("FlowEntry.demand must be non-negative")
88+
if float(self.placed) < 0.0:
89+
logger.error("FlowEntry.placed must be non-negative: %r", self.placed)
90+
raise ValueError("FlowEntry.placed must be non-negative")
91+
if float(self.dropped) < 0.0:
92+
# Clamp tiny negative values caused by rounding noise
93+
if abs(float(self.dropped)) <= 1e-9:
94+
logger.debug(
95+
"Normalizing tiny negative FlowEntry.dropped %.12g to 0.0",
96+
float(self.dropped),
97+
)
98+
self.dropped = 0.0
99+
else:
100+
logger.error("FlowEntry.dropped must be non-negative: %r", self.dropped)
101+
raise ValueError("FlowEntry.dropped must be non-negative")
85102

86103
# Consistency: dropped ≈ demand - placed
87104
expected_drop = float(self.demand) - float(self.placed)

tests/results/test_flow_models_unit.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ def test_flow_iteration_result_validation_and_to_dict() -> None:
152152
FlowIterationResult(flows=[e1, e1], summary=s)
153153

154154

155+
def test_flowentry_negative_dropped_due_to_rounding_is_clamped() -> None:
156+
# Introduce a tiny negative dropped within tolerance due to rounding
157+
e = FlowEntry(
158+
source="S",
159+
destination="D",
160+
priority=0,
161+
demand=100.0,
162+
placed=100.0 + 5e-12, # implies dropped ~ -5e-12
163+
dropped=-5e-12,
164+
)
165+
assert e.dropped == 0.0
166+
167+
155168
def test_ensure_json_safe_errors() -> None:
156169
with pytest.raises(TypeError):
157170
_ensure_json_safe({"k": {1, 2, 3}})

0 commit comments

Comments
 (0)