Add ten Berge & Zegers mu reliability lower-bound series (mu0-mu3) - #226
Merged
Merged
Conversation
Extends mlsirm_core::reliability with tenberge_mu, transcribed from CRAN psych 2.6.5 tenberge.R (read line by line; ten Berge & Zegers, 1978, cited as-cited-in Revelle, 2025). On the Pearson correlation matrix with Vt = sum(R), off-diagonal power sums S_k, and c = p/(p-1) on the innermost radical only: mu0 = c*S1/Vt (= alpha = Guttman lambda3), mu1 = (S1 + sqrt(c*S2))/Vt (= Guttman lambda2), mu2 and mu3 nest one and two further radicals over S4 and S8. Series ordering mu0 <= mu1 <= mu2 <= mu3 follows from Cauchy-Schwarz over the p*(p-1) off-diagonal cells. Divergences documented in the module: raw-data input only, hard errors on degenerate input, S1 by direct off-diagonal summation. Exposes tenberge_mu through the PyO3 binding and the fast_mlsirm.reliability wrapper returning TenBergeResult. Tests: two fixtures pinned at 1e-9 against an independent NumPy replication, exact-identity cross-checks vs guttman_lambdas (both sides crate outputs from independent code paths), rejection paths, ordering asserts on crate outputs, and a 500-rep tau-equivalent Monte Carlo (#[ignore]). Mutation kills verified by hand (innermost-c drop, S2-for-S4 swap, flattened mu3 nesting). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds the ten Berge & Zegers (1978) mu reliability lower-bound series (mu0–mu3) to the reliability toolkit, extending the existing Rust-backed reliability metrics (e.g., Guttman lambdas) with a documented, tested implementation and a Python-facing API.
Changes:
- Implement
tenberge_muandTenBergeResultinmlsirm_core::reliabilityusing off-diagonal power sums over the Pearson correlation matrix. - Expose the new statistic through the PyO3
_coremodule and a thin Python wrapper (fast_mlsirm.tenberge_mu -> TenBergeResult). - Add Rust + Python fixture tests (including ordering assertions and degenerate-input rejections) and document the feature in the changelog.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
crates/mlsirm-core/src/reliability.rs |
Implements tenberge_mu (mu0–mu3) with documented contract and input validation. |
crates/fast-mlsirm-py/src/lib.rs |
Adds PyO3 binding tenberge_mu returning a dict of mu0–mu3. |
python/fast_mlsirm/reliability.py |
Introduces TenBergeResult dataclass and the tenberge_mu Python wrapper. |
python/fast_mlsirm/__init__.py |
Re-exports tenberge_mu / TenBergeResult and adds them to the public API list. |
tests/unit/reliability_tests.rs |
Adds Rust fixture tests, identity cross-checks vs Guttman outputs, and rejection tests. |
tests/test_paper_features.py |
Adds Python fixture parity test and degenerate-input rejection coverage. |
CHANGELOG.md |
Documents the new ten Berge mu series feature and its contract/verification notes. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the ten Berge & Zegers (1978) mu reliability lower-bound series (mu0-mu3) in
mlsirm_core::reliability, with PyO3 binding and thin Python wrapper (fast_mlsirm.tenberge_mu->TenBergeResult). Stacked on #225 (Guttman lambdas).Sources actually read
tenberge.R(14 lines) — read in full (oracle).Contract (on the Pearson correlation matrix; Vt = sum(R), S_k = sum of off-diagonal R^k, c = p/(p-1) innermost only)
mu0 = c*S1/Vt(= coefficient alpha = Guttman lambda3)mu1 = (S1 + sqrt(c*S2))/Vt(= Guttman lambda2)mu2 = (S1 + sqrt(S2 + sqrt(c*S4)))/Vtmu3 = (S1 + sqrt(S2 + sqrt(S4 + sqrt(c*S8))))/Vtmu0 <= mu1 <= mu2 <= mu3proven via Cauchy-Schwarz over the p*(p-1) off-diagonal cells (documented in module docs; asserted on crate outputs).Adversarial spec-verify (before implementation): GO-WITH-FIXES, all applied
Declared divergences from psych (documented in module docs)
Raw-data input only (no correlation-matrix passthrough via the fragile
dim[1] > nheuristic, nouse="pairwise"); hard errors on degenerate input instead of NA propagation.Evidence
cargo test -p mlsirm-coreKnown identity limits disclosed in the test header (mu0/mu1 equal existing Guttman outputs by exact algebra — anchored by independent NumPy literals; all-cells vs 2x-upper-triangle S_2 unkillable for symmetric R).