fix(incremental): Avg rounds the exact mean once, core pins exact sums, Meter counts sum updates; notes and evidence (improvise-hrjz)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
This commit is contained in:
Claude (dbsp-backend)
2026-10-10 16:12:21 -07:00
committed by Edward Langley
parent 10f63cdef9
commit e4c6838d28
7 changed files with 74 additions and 36 deletions
+2 -3
View File
@@ -70,9 +70,8 @@ fn same_bits(change: &CellChange) -> bool {
}
impl Shape {
/// The canonical delta moves counts and multisets; the raw changes move sums and the sign of
/// a zero, which tell the two zeros apart. Returns the group updates the delta caused
/// and the sum updates the changes caused.
/// The delta moves counts and multisets; the raw changes move sums and the sign of a zero.
/// Returns the group updates and the sum updates.
fn apply(&mut self, cats: &[String], delta: &CellDelta, changes: &[CellChange]) -> (u64, u64) {
let (mut updates, mut sums) = (0, 0);
let mut touched = Vec::new();
@@ -33,12 +33,6 @@ fn model_of(values: &[f64], func: AggFunc) -> Model {
model
}
fn exact(values: &[f64]) -> f64 {
let mut sum = ExactSum::new();
values.iter().for_each(|v| sum.add(*v, 1));
sum.value()
}
/// Both backends' sum of `values` under `func`, as bits.
fn both(values: &[f64], func: AggFunc) -> (Option<u64>, Option<u64>) {
let model = model_of(values, func);
+2 -3
View File
@@ -155,9 +155,8 @@ impl ExactSum {
}
}
/// The exact sum divided by `count`, rounded once: a mean that neither overflows with the
/// sum nor rounds twice. Non-finite sums and the sign of a zero read as `value` does.
/// Panics on a zero `count`.
/// The exact sum over `count`, rounded once, so the mean neither overflows nor rounds twice.
/// Non-finite sums and a zero's sign read as `value` does. Panics on a zero `count`.
pub fn mean(&self, count: u64) -> f64 {
assert!(count > 0, "the mean of nothing");
match (self.nan != 0, self.pos_inf != 0, self.neg_inf != 0) {
@@ -1,7 +0,0 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc da6d39e3f2d54dc796842f642b0fc17d09a1491a9937c3d3f95d453d2d9487ed # shrinks to prior = [(3, -1)], snapshot = [(3, 2), (5, -2), (0, 1), (1, 1)], chunk = 0, budget = 1
@@ -1,7 +0,0 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc b276367684808122e5f3fedb8e87a6ab970895f3efce9e6b98a40ade2cdb7227 # shrinks to prior = ZSet { weights: {} }, snap = ZSet { weights: {0: -1, 1: -1} }, post = ZSet { weights: {} }, chunk = 0, budget = 1