Skip to content
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
210 commits
Select commit Hold shift + click to select a range
f8a547e
feat(marginal): MMLE-EM estimator for the latent-space family with mu…
seonghobae Jul 14, 2026
90aa28d
feat(fitstats): S-X2, l_z/l_z* person fit, item screening pipeline, a…
seonghobae Jul 14, 2026
fed0915
docs(changelog) + feat(cli): document the marginal-estimator feature …
seonghobae Jul 14, 2026
cb3ba11
feat: QMC/MC-EM rules, Rust scoring (EAP/MAP/EAPsum) + fitstats core,…
seonghobae Jul 14, 2026
b2580cf
docs: phase-2 design notes (QMC/MC-EM, scoring, FIPC, numerical caveats)
seonghobae Jul 14, 2026
53cf222
feat: paper batch 1 — zero-inflated mixture, position covariate, vali…
seonghobae Jul 14, 2026
dda42fa
feat(oakes): Oakes-identity standard errors for marginal fits (Pritik…
seonghobae Jul 14, 2026
31f71b0
docs(papers): implemented-literature map + group A/B/C implementation…
seonghobae Jul 14, 2026
85fe795
feat: paper batch 3 — information/CAT/plausible values, residual & pa…
seonghobae Jul 14, 2026
d1311b2
feat(fitstats): Chen-Thissen (1997) local-dependence indices; batch-4…
seonghobae Jul 14, 2026
35d343f
feat(scoring): empirical EAP reliability (Stanley-Edwards 2016; Milan…
seonghobae Jul 14, 2026
4e8a143
feat(bifactor): BIFAC2PLM via an inner-product interaction kind
seonghobae Jul 14, 2026
0de3f69
feat(fitstats): M2 limited-information GOF with RMSEA2 CI and SRMSR
seonghobae Jul 14, 2026
7130c3d
feat(linking): moment + Haebara + Stocking-Lord IRT scale linking
seonghobae Jul 14, 2026
4bae160
test(coverage): cover linking + M2 branches; docstrings on new helpers
seonghobae Jul 14, 2026
d643dee
fix(security): harden untrusted input boundaries (Strix VULN-0001..0007)
seonghobae Jul 14, 2026
1cc0a31
test(coverage): cover node/quadrature/parse/validate defensive branches
seonghobae Jul 14, 2026
5f776db
fix(security): finite/bounded numeric config + n_draws/n_dims guards
seonghobae Jul 14, 2026
77946dd
fix(config): keep validation messages backward-compatible after harde…
seonghobae Jul 14, 2026
c2048ef
feat(gpu): GPU EAP scoring kernel (score_pass), opt-in via Device
seonghobae Jul 14, 2026
b5d9d90
security: harden 11 second-pass Strix findings on PR #160 paper-featu…
seonghobae Jul 14, 2026
c3b9e99
security: chase Strix batch-3 (11 findings) + proactive boundary audi…
seonghobae Jul 14, 2026
8d6f3b7
security: Rust-core backstops from the boundary audit (OOB/panic guards)
seonghobae Jul 14, 2026
a89f4ae
docs: GPCM/nominal polytomous kernel design spec (for the next model-…
seonghobae Jul 14, 2026
24d34f1
gpcm: NumPy parity oracle for the unified softmax category cell
seonghobae Jul 14, 2026
939c305
gpcm: analytic M-step gradient reference (FD-verified)
seonghobae Jul 14, 2026
0a50e81
gpcm: NumPy GPCM MMLE-EM reference fitter (recovery-verified)
seonghobae Jul 14, 2026
318eebb
docs: resolve the polytomous-LSIRM design fork from the literature
seonghobae Jul 14, 2026
8a155b6
gpcm: polytomous response cells + gradients in Rust (the compute path)
seonghobae Jul 14, 2026
7dccfea
docs: keep the polytomous design spec model-generic
seonghobae Jul 14, 2026
7415b52
gpcm: unidimensional polytomous marginal-EM fitter in Rust
seonghobae Jul 14, 2026
f0bcf09
gpcm: expose the Rust polytomous fitter via PyO3 with cross-language …
seonghobae Jul 14, 2026
d8afb84
gpcm: public fit_polytomous API (GRM/GPCM, compute in Rust)
seonghobae Jul 14, 2026
5f2ac1e
gpcm: polytomous EAP scoring (fit -> score), compute in Rust
seonghobae Jul 14, 2026
cc3cd96
gpcm: NumPy GRM cell parity mirror (completes the cell parity contract)
seonghobae Jul 14, 2026
a1a96bd
gpcm: polytomous item/test information curves (compute in Rust)
seonghobae Jul 14, 2026
02b7287
docs: record polytomous scoring and information in the changelog
seonghobae Jul 14, 2026
f161c25
gpcm: missing-data support for the polytomous fitter and scorer
seonghobae Jul 14, 2026
d6b25d0
docs: note missing-data (NaN) handling in the polytomous changelog entry
seonghobae Jul 14, 2026
6e19799
gpcm: latent-space polytomous LSIRM estimator + rigorous validation
seonghobae Jul 14, 2026
3f9db61
gpcm: extend K=2 cross-validation to GRM + RMSE under missingness
seonghobae Jul 14, 2026
b343322
gpcm: person scores + Python API for the latent-space polytomous LSIRM
seonghobae Jul 14, 2026
97a9642
gpcm: polytomous model-selection indices (Kang, Cohen & Sung 2009)
seonghobae Jul 14, 2026
a5f5435
gpcm: generalized S-X2 polytomous item fit (Kang & Chen 2008/2011)
seonghobae Jul 14, 2026
8714fd2
gpcm: Python API for generalized S-X2 polytomous item fit + APA 7th refs
seonghobae Jul 14, 2026
83b626d
gpcm: Monte-Carlo recovery study (normal vs skew ability), RMSE + bias
seonghobae Jul 14, 2026
04cd989
gpcm: split MC recovery into fast CI guard + 500-replication study
seonghobae Jul 14, 2026
ea5de5f
gpcm: polytomous M2 limited-information GOF (Maydeu-Olivares & Joe 2014)
seonghobae Jul 14, 2026
fa2d5bc
gpcm: Python API for polytomous M2 goodness-of-fit + APA 7th refs
seonghobae Jul 14, 2026
a5e6348
gpcm: polytomous item-pair local dependence (Chen & Thissen 1997)
seonghobae Jul 14, 2026
dd72681
gpcm: Python API for polytomous local dependence + APA 7th refs
seonghobae Jul 14, 2026
7ddc825
gpcm: nominal categories model estimator (Thissen, Cai & Bock 2010; B…
seonghobae Jul 14, 2026
983690e
gpcm: Python API for the nominal categories model + APA 7th refs
seonghobae Jul 14, 2026
a44c648
gpcm: polytomous person fit l_z / l_z* (Drasgow-Levine-Williams 1985;…
seonghobae Jul 14, 2026
7698888
gpcm: Python API for polytomous person fit (l_z / l_z*) + APA 7th refs
seonghobae Jul 14, 2026
a62a9b8
gpcm: polytomous computerized adaptive testing (Dodd, De Ayala & Koch…
seonghobae Jul 14, 2026
16dd41f
gpcm: Python API for polytomous CAT simulation + APA 7th refs
seonghobae Jul 14, 2026
3e9e834
Add polytomous IRT likelihood-ratio DIF (two-group marginal EM)
seonghobae Jul 14, 2026
772b61a
Add nonparametric polytomous person-fit U3poly (Emons 2008)
seonghobae Jul 14, 2026
8999fe0
Add observed-score equating (Kolen & Brennan)
seonghobae Jul 14, 2026
a587806
Add kernel equating and log-linear presmoothing
seonghobae Jul 14, 2026
b4c218a
Add Tucker & Levine linear NEAT equating
seonghobae Jul 14, 2026
ddf00a6
Add standard errors of equating (bootstrap + delta-method)
seonghobae Jul 14, 2026
f0d6f12
Add lognormal response-time model (van der Linden, 2007)
seonghobae Jul 14, 2026
ed991f5
Add joint speed-accuracy model (van der Linden, 2007, Level 2)
seonghobae Jul 14, 2026
73e55f8
Add response-time person fit (van der Linden & Guo, 2008)
seonghobae Jul 14, 2026
f510861
Add DINA/DINO cognitive diagnosis models
seonghobae Jul 14, 2026
dfdcf13
fix(rt): correct fixed-variance covariance update
seonghobae Jul 14, 2026
296d1cd
fix(cdm): validate EM inputs and source attribution
seonghobae Jul 14, 2026
46e7c7c
fix(marginal): align EM trace with returned parameters
seonghobae Jul 15, 2026
03ca21a
Add generalized DINA (G-DINA) saturated cognitive diagnosis model
seonghobae Jul 15, 2026
8d0406d
fix(marginal): align NumPy EM endpoint with Rust
seonghobae Jul 15, 2026
733e709
test(marginal): require explicit CPU-GPU parity
seonghobae Jul 15, 2026
5592ca1
fix(coverage): gate GPU EAP test with GPU implementation
seonghobae Jul 15, 2026
768091f
ci(coverage): declare Rust workspace baseline
seonghobae Jul 15, 2026
273ba6a
docs(scoring): normalize the EAP source to APA 7
seonghobae Jul 15, 2026
ae9a625
Add mixed Rasch / mixture IRT (Rost, 1990)
seonghobae Jul 15, 2026
02ece77
fix(oakes): skip absent tau coordinate in bifactor scores
seonghobae Jul 15, 2026
b99a83c
fix(mixture): validate dimensions and correct estimator provenance
seonghobae Jul 15, 2026
a7f0430
docs(mixture): cite the chapter-level Rasch mixture DOI
seonghobae Jul 15, 2026
dd55860
Add Linear Logistic Test Model (Fischer, 1973)
seonghobae Jul 15, 2026
9451f2d
fix(bifactor): use inner-product eta for covariates
seonghobae Jul 15, 2026
977f705
docs(lltm): distinguish marginal EM from Fischer CML
seonghobae Jul 15, 2026
e00afc3
fix(dif): compact sparse group labels
seonghobae Jul 15, 2026
03363b7
feat(fitstats): add estimator-aware structured M2 diagnostics
seonghobae Jul 15, 2026
26242a5
feat(mixed): calibrate heterogeneous item families jointly
seonghobae Jul 15, 2026
b7198cf
feat(mixed): add constrained response families
seonghobae Jul 15, 2026
7f5e406
Add testlet response model (Bradlow, Wainer, & Wang, 1999)
seonghobae Jul 15, 2026
b78da9f
fix(testlet): make convergence termination explicit
seonghobae Jul 15, 2026
c246af7
fix(rt): expose joint calibration termination evidence
seonghobae Jul 15, 2026
5cdc61e
Add empirical Q-matrix validation (de la Torre & Chiu, 2016)
seonghobae Jul 15, 2026
3e9cb0e
Add item-level CDM model selection by the Wald test (de la Torre, 2011)
seonghobae Jul 15, 2026
70d7723
fix(cdm): reject Q validation after unconverged calibration
seonghobae Jul 15, 2026
607b3e0
fix(cdm): reject Wald selection after unconverged calibration
seonghobae Jul 15, 2026
d20cd64
fix(mixed): implement the paired-category GGUM probability
seonghobae Jul 15, 2026
3af7b6c
Add higher-order structured attribute prior for CDM (de la Torre & Do…
seonghobae Jul 15, 2026
55636fd
fix(fitstats): reject M2 diagnostics for nonconverged fits
seonghobae Jul 15, 2026
e6ed564
fix(cdm): safeguard higher-order EM convergence
seonghobae Jul 15, 2026
803163b
Add DINO to item-level CDM Wald model selection (de la Torre, 2011)
seonghobae Jul 15, 2026
f07e94a
fix(fitstats): count FIPC free parameters in M2
seonghobae Jul 15, 2026
dc19938
fix(polytomous): report true EM convergence
seonghobae Jul 15, 2026
2d5acbb
Add the Continuous Response Model (Samejima, 1973)
seonghobae Jul 15, 2026
2a5bab8
fix(crm): enforce identifiable EM convergence
seonghobae Jul 15, 2026
15e7dba
Add the Rating Scale Model (Andrich, 1978)
seonghobae Jul 15, 2026
d82db85
fix(fitstats): fail closed on unfinished item screening
seonghobae Jul 15, 2026
bcfb30c
fix(rsm): reject unidentified and malformed fits
seonghobae Jul 15, 2026
dc042f6
fix(poly): make nominal EM convergence explicit
seonghobae Jul 15, 2026
ec0cb81
fix(fitstats): reject M2 from unconverged polytomous fits
seonghobae Jul 15, 2026
e4dbe5e
Add the higher-order G-DINA model (de la Torre & Douglas, 2004; de la…
seonghobae Jul 15, 2026
ab64357
fix(equating): reject unconverged presmoothing
seonghobae Jul 15, 2026
b75084f
fix(cdm): enforce higher-order G-DINA convergence
seonghobae Jul 15, 2026
47360f2
feat(cdm): add LLM and R-RUM to the Wald item-model selection
seonghobae Jul 15, 2026
03098e8
feat(cdm): add shared-Q sequential G-DINA for polytomous responses
seonghobae Jul 15, 2026
2733c51
fix(scoring): validate CAT and reliability inputs
seonghobae Jul 15, 2026
ae9e714
fix(cdm): expose sequential G-DINA termination evidence
seonghobae Jul 15, 2026
74d0076
fix(marginal): validate FIPC and final convergence
seonghobae Jul 15, 2026
3bf4c0f
fix(fitstats): validate LD index inputs
seonghobae Jul 15, 2026
15bfe96
fix(linking): validate scales and report convergence
seonghobae Jul 15, 2026
bc826fc
feat(mirt): add orthogonal confirmatory compensatory MIRT
seonghobae Jul 15, 2026
4d44eb9
fix(scoring): reject malformed Rust inputs
seonghobae Jul 15, 2026
b4dfad2
fix(mirt): preserve input and convergence contracts
seonghobae Jul 16, 2026
2142581
fix(polytomous): validate EAP scoring inputs
seonghobae Jul 16, 2026
e405d75
fix(serving): bound information and plausible-value requests
seonghobae Jul 16, 2026
d637de1
fix(polytomous): validate information curve inputs
seonghobae Jul 16, 2026
4816f99
fix(polytomous): align NumPy EM convergence state
seonghobae Jul 16, 2026
3aafc67
fix(serving): validate dense scoring matrices
seonghobae Jul 16, 2026
8833d31
fix(polytomous): stabilize GRM tail categories
seonghobae Jul 16, 2026
2d14f37
feat(mirt): estimate a free latent correlation matrix (correlated MIRT)
seonghobae Jul 16, 2026
1739dbd
fix(security): bound NumPy inputs and scoring parameters
seonghobae Jul 16, 2026
823dbb7
feat(cdm): per-step-Q sequential G-DINA (Ma & de la Torre, 2016 full …
seonghobae Jul 16, 2026
cee5145
fix(security): bound native model dimensions
seonghobae Jul 16, 2026
ffd2ac6
fix(polytomous): fail closed on unconverged DIF fits
seonghobae Jul 16, 2026
5b97972
fix(config): bound L-BFGS history memory
seonghobae Jul 16, 2026
4a80c13
fix(security): reject aliased factor identifiers
seonghobae Jul 16, 2026
3f80957
fix(nodes): bound stochastic node allocation
seonghobae Jul 16, 2026
8a20ac8
fix(testlet): bound native calibration inputs
seonghobae Jul 16, 2026
6c19e35
feat(mirt): D>3 compensatory MIRT via quasi-Monte-Carlo EM (Jank, 2005)
seonghobae Jul 16, 2026
3b1aa41
feat(nominal): confirmatory multidimensional nominal response model (…
seonghobae Jul 16, 2026
e239904
fix(nominal): reject fractional category labels
seonghobae Jul 16, 2026
661adb4
fix(fit): reject fractional factor identifiers
seonghobae Jul 16, 2026
7fefd6a
feat(grm): confirmatory multidimensional graded response model (Samej…
seonghobae Jul 16, 2026
d7b6549
refactor(api): unify IRT models by item family
seonghobae Jul 16, 2026
c54c79b
fix(rust): disambiguate nominal estimator test
seonghobae Jul 16, 2026
cc821ec
feat(gpcm): confirmatory multidimensional generalized partial credit …
seonghobae Jul 16, 2026
373f815
feat(mhrm): high-dimensional confirmatory 2PL by Metropolis-Hastings …
seonghobae Jul 16, 2026
1eda32d
feat(mhrm): estimate a free latent factor correlation (Cai, 2010b)
seonghobae Jul 16, 2026
13873c9
feat(mhrm): add the polytomous GPCM response family (Muraki, 1992)
seonghobae Jul 16, 2026
fb403df
fix(security): bound text and estimator allocations
seonghobae Jul 16, 2026
a3c587e
docs(citations): disambiguate MH-RM sources
seonghobae Jul 16, 2026
bac254b
fix(mirt): bound node-item E-step tables
seonghobae Jul 16, 2026
d2a2d29
feat(dif): add observed-score Mantel-Haenszel DIF (Holland & Thayer, …
seonghobae Jul 16, 2026
b0374f3
feat(scoring): add Warm's weighted likelihood ability estimation (War…
seonghobae Jul 16, 2026
999a33d
feat(rasch-cml): add conditional ML + Andersen's LR test (Andersen, 1…
seonghobae Jul 16, 2026
8bf93f4
fix(rasch): reject non-finite Andersen groups
seonghobae Jul 18, 2026
5950748
fix(serving): validate population object shape
seonghobae Jul 18, 2026
e2e6f91
fix(polytomous): bound native fit inputs
seonghobae Jul 19, 2026
d7063f7
fix(mhrm): report the actual stopping metric
seonghobae Jul 20, 2026
8c481fe
fix(scoring): resolve narrow WLE global modes
seonghobae Jul 20, 2026
d0ac608
fix(fitstats): reject unsupported structured M2
seonghobae Jul 20, 2026
b0c51e6
feat(dif): add Zumbo logistic-regression DIF with non-uniform detection
seonghobae Jul 20, 2026
1484665
fix(fitstats): stabilize noncentral chi-square tails
seonghobae Jul 20, 2026
c0da992
fix(rt): expose calibration termination evidence
seonghobae Jul 20, 2026
414ff35
fix(rt): reject unidentified joint calibrations
seonghobae Jul 20, 2026
c4e6352
fix(rt): reject non-finite person-fit states
seonghobae Jul 20, 2026
fd38d41
fix(cdm): correct G-DINA monotonicity contract
seonghobae Jul 20, 2026
4c37760
fix(cdm): correct sequential recovery evidence
seonghobae Jul 20, 2026
92714c5
fix(coverage): enforce complete Rust line coverage
seonghobae Jul 20, 2026
5e83705
test(bifactor): require recovery convergence
seonghobae Jul 20, 2026
e9617df
fix(serving): reject nonconverged calibration bundles
seonghobae Jul 20, 2026
108f84c
test(cli): cover serving score command
seonghobae Jul 20, 2026
e2aebb8
docs(scoring): correct multidimensional CAT citation
seonghobae Jul 20, 2026
e111b07
test(fitstats): cover empirical reliability wrapper
seonghobae Jul 21, 2026
53057f0
fix(security): bound fit requests and harden artifact writes
seonghobae Jul 21, 2026
8bb1c4b
fix(security): close remaining public input boundaries
seonghobae Jul 21, 2026
e53d93a
test(rsm): enforce Monte Carlo convergence evidence
seonghobae Jul 21, 2026
9971b4c
fix(rt): bound joint calibration iterations
seonghobae Jul 21, 2026
4a1f432
fix(testlet): bound calibration iterations
seonghobae Jul 21, 2026
da3382d
fix(crm): bound calibration iterations
seonghobae Jul 21, 2026
732846f
fix(equating): reject oversized SEE buffers
seonghobae Jul 21, 2026
3b17e6b
fix(oakes): reject invalid inference states
seonghobae Jul 21, 2026
1e66712
fix(fipc): reject non-boolean anchor masks
seonghobae Jul 21, 2026
61b6e34
fix(config): validate stochastic integration controls
seonghobae Jul 21, 2026
40260ea
fix(scoring): enforce MAP convergence and information
seonghobae Jul 21, 2026
0ef57b4
fix(fitstats): harden S-X2 boundaries
seonghobae Jul 21, 2026
df40587
fix(fitstats): validate person diagnostics
seonghobae Jul 21, 2026
fdc40c1
fix(fitstats): reject invalid Vuong inputs
seonghobae Jul 21, 2026
295bd9b
fix(marginal): honor zero-inflation in multilevel EAP
seonghobae Jul 21, 2026
be02807
fix(polytomous): preserve undefined AICc boundary
seonghobae Jul 21, 2026
87c6669
fix(dif): align LR calibration with fitted parameters
seonghobae Jul 21, 2026
643ecc4
fix: align bifactor residual diagnostics with model algebra
seonghobae Jul 21, 2026
0f1a4cc
fix: validate IRTree mapping contracts
seonghobae Jul 21, 2026
71cf487
fix(fitstats): sign LD statistics by phi correlation
seonghobae Jul 21, 2026
762167f
fix(fitstats): reject invalid residual diagnostics
seonghobae Jul 22, 2026
5e8ff08
fix(fitstats): validate adjusted pairwise diagnostics
seonghobae Jul 22, 2026
47fb6bf
feat(dif): iterative item purification for observed-score DIF
seonghobae Jul 22, 2026
e06c747
fix(fitstats): constrain resampled person fit
seonghobae Jul 22, 2026
0c6a139
fix(dif): report purification termination
seonghobae Jul 22, 2026
32ee366
fix(fitstats): validate TCC drift termination
seonghobae Jul 22, 2026
670a138
test(cdm): restore converged Q-validation recovery
seonghobae Jul 22, 2026
1a25e0c
fix(cdm): expose Q-validation convergence evidence
seonghobae Jul 22, 2026
22ceede
feat(dif): uniform SIBTEST with the regression-corrected criterion
seonghobae Jul 22, 2026
7644999
fix(cdm): expose higher-order stopping evidence
seonghobae Jul 22, 2026
681eba1
feat(scoring): prefer GPU for EAP execution
seonghobae Jul 22, 2026
62d100b
fix(serving): keep EAP execution inside Rust
seonghobae Jul 22, 2026
443ee74
feat(scoring): offload CAT information to GPU
seonghobae Jul 22, 2026
8d50e17
feat(scoring): offload plausible values to GPU
seonghobae Jul 22, 2026
9b4b297
feat(scoring): offload EAPsum scoring to GPU
seonghobae Jul 22, 2026
605920a
feat(scoring): Warm weighted-likelihood ability for polytomous items
seonghobae Jul 22, 2026
48712f6
feat(scoring): run empirical reliability on GPU
seonghobae Jul 22, 2026
1243031
test(scoring): skip GPU parity without adapter
seonghobae Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,89 @@

## Unreleased

### Added

- **Marginal (MMLE-EM) estimation for the full latent-space family.**
`fit(estimator="mmle")` now fits `MIRT`/`MLS2PLM`/`MLSRM` (and `ULS2PLM`/
`ULSRM` under a population structure) by Bock-Aitkin-style marginal EM:
person latents `(theta, xi)` are integrated over Gauss-Hermite grids —
tractable via the simple-structure conditional factorization — with a
Fisher-preconditioned GEM M-step and the Jeon et al. (2021) LSIRM priors as
MAP penalties (`PenaltyConfig::lsirm_prior`). Rust core
(`mlsirm_core::marginal`) with a NumPy mirror
(`fast_mlsirm.estimators.marginal`) held to 1e-9 end-of-run parity
(`tests/test_marginal_parity.py`); design and paper basis in
`docs/mmle_marginal_lsirm_design.md`.
- **Estimation-level multigroup and multilevel population structures** for the
marginal estimator: `fit(..., group_id=...)` (Bock-Zimowski group trait
means/SDs, common items, pinned reference group) and
`fit(..., cluster_id=...)` (Fox-Glas random intercept, `sigma_u`/ICC
estimated). Results surface on `FitResult.population` and persist through
`save_fit_result`; the CLI `fit` command gains `--estimator`, `--group-id`,
`--cluster-id`, `--q-theta`, `--q-xi`, `--q-u`, and `--tolerance`.
- **wgpu E-step kernels for the marginal estimator**
(`mlsirm_core::gpu_marginal`): the E-step hot path runs in f32 on the GPU
with the same race-free slot-ownership reduction as the JML kernels, cutting
a 31k-person multilevel E-step iteration from ~110 s (CPU f64) to ~5 s on a
laptop RTX 3050 Ti; the M-step and final EAP pass stay on the CPU in f64,
and hosts without an adapter fall back to the CPU path unchanged.
- **Likelihood-based fit statistics** (`fast_mlsirm.fitstats`): Orlando-Thissen
S-X² via the Lord-Wingersky recursion generalized to the joint `(theta, xi)`
grid (chi-square tail without SciPy), Benjamini-Hochberg FDR control,
Drasgow `l_z` and Snijders `l_z*` person fit with the MAP `r_0` correction,
and infit/outfit at the marginal EAPs.
- **Item screening pipeline** (`fast_mlsirm.select_items`): iterative
fit → flag → remove → refit with sparse / S-X²-BH / mean-square band /
low-discrimination / map-isolation flags, an `l_z*` person screen, a
per-dimension item floor, and a full audit trail.
- **Serving bundle + frozen-parameter scoring** (`fast_mlsirm.serving`):
schema-versioned JSON bundle of the calibrated item parameters and
population block, and `score_respondents()` EAP scoring of new response
payloads with items frozen — the fixed-parameter serving pattern used by
the downstream importance-assessment API. `fast-mlsirm score` scores a JSON
payload (or `.npy` matrix) against a bundle from the command line.

- **QMC-EM and MC-EM integration rules** for the marginal estimator
(`FitConfig(xi_rule="qmc"|"mc", xi_points=..., xi_seed=...)`): the
latent-space integral runs on Halton low-discrepancy points (randomized-QMC
shift optional; Jank 2005) or seeded Monte Carlo draws (Wei & Tanner 1990;
Meng & Schilling 1996) instead of the tensor Gauss-Hermite grid — enabling
`latent_dim > 3` and better error scaling per node. Both constructions are
deterministic and bit-mirrored across the Rust/NumPy backends.
- **Rust scoring module** (`mlsirm_core::scoring`, exposed via
`_core.score_bank_eap` / `score_bank_map` / `eapsum_tables`): EAP
(Bock & Mislevy 1982), MAP (posterior Newton with observed-information
SEs), and summed-score EAP conversion tables via the Lord-Wingersky
recursion (Thissen et al. 1995; Cai 2015), all under per-dimension
`N(mean_d, sd_d^2)` priors that cover single, multigroup
(`mu_g, sigma_g`) and multilevel populations (conditional
`N(u_hat_c, 1)` or marginal `N(0, sqrt(1 + sigma_u^2))`).
`score_respondents(..., method="eap"|"map"|"eapsum", prior=...)` and the
bundle's embedded `eapsum_tables` expose these to serving.
- **Fit statistics moved to the Rust core** (`mlsirm_core::fitstats`): S-X²,
Benjamini-Hochberg, `l_z`/`l_z*`, infit/outfit now compute in Rust
(`fast_mlsirm.fitstats` delegates; the NumPy bodies remain the parity
reference/fallback). S-X² gains the `rms_residual` practical-significance
effect size (Sinharay & Haberman 2014) and `select_items` gates its flag on
`sx2_min_effect`; the mean-square gate now uses infit only (outfit is
reported, not gating — it explodes under very low pass rates); the person
screen threshold is configurable and the Snijders `r_0` correction is
centered on the population prior mean (cluster intercepts / group means).
- **Fixed Item Parameter Calibration** (`fit(..., anchors=...)`): anchored
items stay frozen (optionally `tau` too) while new items and a freed
population mean/SD are estimated — the multiple-cycle prior-update (MWU-MEM
style) variant Kim (2006) found robust; latent-space orientation inherits
from the anchors (no PCA re-alignment). **Concurrent calibration** is the
existing multigroup path with structural missingness (Hanson & Béguin
2002), covered by a dedicated recovery test.

### Changed

- `estimator="mmle"` with a spatial/multidimensional model now fits (routed to
the marginal estimator) instead of raising `NotImplementedError`; plain
`ULS2PLM`/`ULSRM` without a population structure keep the legacy
unidimensional fast path and its exact previous behavior.

- Exposed the Rust MMLE-EM estimator (`mlsirm_core::mmle::fit_mmle_2pl`) through
the PyO3 binding as `fast_mlsirm._core.fit_mmle_2pl`, so
`fit(estimator="mmle")` now runs on the Rust core when the extension is built
Expand Down
4 changes: 2 additions & 2 deletions crates/fast-mlsirm-py/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading