You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GeneralizedTableauSum with sum_cutoff=0.0 panics when you build a sampler, for any channel that produces three or more branches. The branch weights sum to 0.9999999999999999 in f64, and the normalization debug_assert uses a strict >= against 1 - sum_cutoff, which at sum_cutoff == 0 leaves no room for rounding.
Reachable from Python, and it surfaces as a PanicException rather than a Python-level error.
thread '<unnamed>' panicked at crates/ppvm-tableau-sum/src/data.rs:136:9:
Normalization error in sum
PanicException: Normalization error in sum
Scope
Any channel whose branch weights don't sum to exactly 1.0 in binary floating point. Two-branch splits are fine because the halves are exact:
operation
sum_cutoff=0.0
depolarize1(0, 0.3)
panics (p/3 is not exact)
pauli_error(0, [0.1, 0.2, 0.3])
panics
correlated_loss_channel(0, 1, [0.1, 0.2, 0.0])
panics
loss_channel(0, 0.1)
ok
x_error(0, 0.1)
ok
Cause
crates/ppvm-tableau-sum/src/data.rs:136:
debug_assert!(*p_cum.last().unwrap_or(&T::Coeff::zero()) >= T::Coeff::one() - self.sum_cutoff.clone(),"Normalization error in sum");
sum_cutoff doubles as both the truncation threshold and the normalization tolerance. That coupling is fine while sum_cutoff is comfortably larger than accumulated f64 error, but at 0.0 the assert demands the cumulative mass be exactly>= 1.0, which a sum of three or more f64 weights generally is not.
Notes
The debug_assert means release wheels don't hit this, so it affects development and maturin develop installs. The invariant it's checking is still worth checking — the issue is the tolerance, not the assert.
Convention-independent: I verified it reproduces with weights from both the old and new correlated-loss conventions, and with channels that have nothing to do with loss.
A plausible fix is to separate the normalization tolerance from sum_cutoff — compare against 1.0 - max(sum_cutoff, k * f64::EPSILON) for a small k, or scale the slack with the branch count.
Summary
GeneralizedTableauSumwithsum_cutoff=0.0panics when you build a sampler, for any channel that produces three or more branches. The branch weights sum to0.9999999999999999inf64, and the normalizationdebug_assertuses a strict>=against1 - sum_cutoff, which atsum_cutoff == 0leaves no room for rounding.Reachable from Python, and it surfaces as a
PanicExceptionrather than a Python-level error.Reproduction
Scope
Any channel whose branch weights don't sum to exactly
1.0in binary floating point. Two-branch splits are fine because the halves are exact:sum_cutoff=0.0depolarize1(0, 0.3)p/3is not exact)pauli_error(0, [0.1, 0.2, 0.3])correlated_loss_channel(0, 1, [0.1, 0.2, 0.0])loss_channel(0, 0.1)x_error(0, 0.1)Cause
crates/ppvm-tableau-sum/src/data.rs:136:sum_cutoffdoubles as both the truncation threshold and the normalization tolerance. That coupling is fine whilesum_cutoffis comfortably larger than accumulatedf64error, but at0.0the assert demands the cumulative mass be exactly>= 1.0, which a sum of three or moref64weights generally is not.Notes
debug_assertmeans release wheels don't hit this, so it affects development andmaturin developinstalls. The invariant it's checking is still worth checking — the issue is the tolerance, not the assert.sum_cutoff— compare against1.0 - max(sum_cutoff, k * f64::EPSILON)for a smallk, or scale the slack with the branch count.🤖 Generated with Claude Code