scikit-bio's Lladser confidence interval for the conditional uncovered probability holds a table of
constants indexed by a rarefaction depth r, one pair (c1, c2) per row. The default lower bound uses
the first constant c1. For r=9 at the 95 percent level the table holds 4.695227540, but that is the
value of an unrelated table, _LOWER_CONFIDENCE_BOUND[9], copied by mistake; the true constant is near
1.44. So lladser_ci(counts, r=9) silently returns a confidence interval about three times wider than
its neighbours at r=8 and r=10.
scikit-bio, skbio/diversity/alpha/_lladser.py, _CB_95, 0.7.3 and current main (identical), line
523, with the value it duplicates at line 407:
_CB_95 = [ ...
(4.695227540, 4.695227541), # r=9: c1 is a copy of _LOWER_CONFIDENCE_BOUND[9], should be ~1.44
... ]
_LOWER_CONFIDENCE_BOUND = { ... 9: 4.695227540, ... }Three self-consistency invariants a correct table satisfies are all violated at r=9, and none requires
knowing the true Maple-computed value: c1 increases with r, but it spikes at r=9; c1 at the 95
percent level lies between its 90 and 99 percent values, but it is far above both; and c1 equals
_LOWER_CONFIDENCE_BOUND[9] exactly. The neighbouring rows and the second constant are correct. The fix is
to replace the constant with its true value, near 1.44.
The 95 percent first constant by r, and the invariants it should satisfy:
95 percent c1 by r: {7: 1.185086998, 8: 1.315076337, 9: 4.69522754, 10: 1.570546801, 11: 1.696229569}
c1 increases with r at r=8: True; at r=9: False
c1(0.95, r=9) between c1(0.90) and c1(0.99): False (0.90 1.299491033, 0.95 4.69522754, 0.99 1.741759456)
c1(0.95, r=9) == _LOWER_CONFIDENCE_BOUND[9]: True
interpolated true c1(0.95, r=9): 1.4428 vs table 4.69522754 (ratio 3.25x)
Driving the real library:
_CB_95[9][0] 4.69522754 == _LOWER_CONFIDENCE_BOUND[9] 4.69522754: True
c1 r=7..11 [1.185086998, 1.315076337, 4.69522754, 1.570546801, 1.696229569]; increases at r=9: False
c1 at r=9: 0.90 1.299491033, 0.95 4.69522754, 0.99 1.741759456; 0.95 between: False
lladser_ci widths {8: 0.05998, 9: 0.18547, 10: 0.05532}; r=9 over neighbours 3.22x, too wide True
sibling c2 at r=9 4.695227541 increases True; c1 equals c2 True
The 95 percent first constant increases smoothly with r at every depth except r=9, where it jumps to
4.695 between 1.315 and 1.571; it is not between its own 90 and 99 percent values; and it equals the
lower-confidence-bound table exactly, the value it was copied from. The real lladser_ci then returns an
interval of width 0.185 at r=9 against 0.060 and 0.055 at r=8 and r=10, 3.22 times wider. The
base case isolates the fault: the second constant c2 at r=9 is larger than c1 and increases with r
correctly, and only at r=9 does c1 wrongly equal c2.
lladser_ci runs with the default confidence type and level, and r=9 is a normal value in the
documented range. The failure is silent: a plausible confidence interval is returned, but it is about three
times too wide, so any coverage or rarefaction analysis at r=9 is wrong. The error is a copied constant,
not floating-point round-off, and it is caught by three independent self-consistency invariants and by
matching the wrong table exactly. The fix is to replace _CB_95[9][0] with its true value near 1.44.
excerpt.py: the_CB_95row and the lower-confidence-bound value quoted with the flags that name the fault, and the three invariants.constants.py: the first constant across depths and confidence levels, with the checks thatc1increases withrand lies between confidence levels, sor=9breaks both and interpolates to1.44.consequence.py: the real skbio constant tables showing the copy and the broken invariants, and the reallladser_ciinterval three times wider atr=9.test_lladserconst.py: the modelr=9breaks monotonicity and confidence ordering and equals the wrong table, the real constant is copied and breaks the invariants, the real interval is too wide, and the siblingc2is correct.
python constants.py
python consequence.py
python test_lladserconst.py
The constant is quoted from current main; the intervals are produced by the real lladser_ci. The fix
is to replace the copied constant with its true value near 1.44.