Commit 3c97dc5
fix(rust): deterministic clustered vcov — first-appearance cluster aggregation
The cluster-score aggregation in compute_robust_vcov (also reached via
solve_ols(return_vcov=True)) built its (G,k) cluster-scores matrix in
HashMap iteration order, which is SipHash-randomized per call:
mathematically identical, but the GEMM accumulation order changed on
every invocation, wobbling the clustered vcov at ~1e-14 (3 distinct
values across 8 identical calls; the Python backend is bit-stable).
Rows now accumulate in first-appearance order — ascending for the
factorized 0..G-1 ids the Python dispatcher passes, matching NumPy's
groupby order. Verified 1 distinct value across 50 identical calls;
NumPy parity unchanged (~1e-14 cross-backend GEMM tolerance).
Bit-identity regression tests cover contiguous and non-contiguous
unsorted cluster ids. Resolves the TODO row currently in flight on
PR #647 (row deletion follows once both merge).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>1 parent c4aaab2 commit 3c97dc5
3 files changed
Lines changed: 62 additions & 12 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
38 | 48 | | |
39 | 49 | | |
40 | 50 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
349 | 349 | | |
350 | 350 | | |
351 | 351 | | |
352 | | - | |
353 | | - | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
354 | 362 | | |
355 | | - | |
356 | | - | |
357 | | - | |
358 | | - | |
359 | | - | |
360 | | - | |
| 363 | + | |
| 364 | + | |
361 | 365 | | |
362 | 366 | | |
363 | | - | |
| 367 | + | |
364 | 368 | | |
365 | 369 | | |
366 | 370 | | |
| |||
369 | 373 | | |
370 | 374 | | |
371 | 375 | | |
372 | | - | |
| 376 | + | |
373 | 377 | | |
374 | | - | |
375 | | - | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
376 | 383 | | |
377 | 384 | | |
378 | 385 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3622 | 3622 | | |
3623 | 3623 | | |
3624 | 3624 | | |
| 3625 | + | |
| 3626 | + | |
| 3627 | + | |
| 3628 | + | |
| 3629 | + | |
| 3630 | + | |
| 3631 | + | |
| 3632 | + | |
| 3633 | + | |
| 3634 | + | |
| 3635 | + | |
| 3636 | + | |
| 3637 | + | |
| 3638 | + | |
| 3639 | + | |
| 3640 | + | |
| 3641 | + | |
| 3642 | + | |
| 3643 | + | |
| 3644 | + | |
| 3645 | + | |
| 3646 | + | |
| 3647 | + | |
| 3648 | + | |
| 3649 | + | |
| 3650 | + | |
| 3651 | + | |
| 3652 | + | |
| 3653 | + | |
| 3654 | + | |
| 3655 | + | |
| 3656 | + | |
| 3657 | + | |
0 commit comments