SPB Git

spb/wp35_uqo

Public
2.6 KB · 46 lines python
1import numpy as np, pandas as pd, pytest2from wp35.measurement.irt import fit_2pl3from wp35.econometrics.common import holm, fold_win_share, oos_loglik_binomial4from wp35.simulations.model import Params, simulate, shannon_lengths, zipf_dist, entropy_bits567def test_irt_recovers_ordering_with_missing_items():8    rng = np.random.default_rng(1); N, J = 400, 129    theta = rng.normal(size=N); b = np.linspace(-1.5, 1.5, J); a = np.full(J, 1.5)10    P = 1 / (1 + np.exp(-a * (theta[:, None] - b[None, :]))); X = (rng.random((N, J)) < P).astype(float)11    X[rng.random((N, J)) < 0.3] = np.nan                     # 30% missing at random, never recoded as 012    f = fit_2pl(X)13    ok = ~np.isnan(f["eap"])14    assert np.corrcoef(f["eap"][ok], theta[ok])[0, 1] > 0.815    assert np.corrcoef(f["b"], b)[0, 1] > 0.9161718def test_holm_and_win_share():19    adj = holm({"a": 0.01, "b": 0.04, "c": 0.20})20    assert adj["a"] == pytest.approx(0.03) and adj["b"] == pytest.approx(0.08) and adj["c"] == pytest.approx(0.20)21    cv = pd.DataFrame({"model": ["m"] * 3 + ["b"] * 3, "fold": [1, 2, 3] * 2, "oos_loglik": [-1, -2, -3, -1.5, -2.5, -2.5]})22    w = fold_win_share(cv, "m", "b"); assert w["folds"] == 3 and w["win_share"] == pytest.approx(2 / 3)23    assert oos_loglik_binomial([1, 0], [0.5, 0.5]) == pytest.approx(np.log(0.5))242526def test_shannon_code_lengths_satisfy_kraft_and_bounds():27    for z in [0.0, 1.0, 2.0]:28        p = zipf_dist(64, z); L = shannon_lengths(p); H = entropy_bits(p)29        assert np.sum(2.0 ** (-L)) <= 1 + 1e-9                  # Kraft30        assert H <= (p * L).sum() < H + 1                        # Theorem 1313233def test_simulation_is_deterministic_and_measures_shock_penalty():34    a = simulate(Params(N=100, regime="norms", seed=3)); b = simulate(Params(N=100, regime="norms", seed=3))35    assert a["success_rate"] == b["success_rate"] and a["bits_per_task"] == b["bits_per_task"]36    s = simulate(Params(N=100, regime="norms", seed=3, shock_type="distribution", shock_period=20, shock_kl_target=2.0, adapt_delay=1000))37    extra_per_recipient = (s["bits_per_task_post"] - s["bits_per_task_pre"]) / (s["k"] - 1)38    assert abs(extra_per_recipient - s["kl_q_p_bits"]) < 1.0      # Theorem 3 within ±1 bit39    assert 0 <= s["success_rate"] <= 1 and s["msgs_per_task"] > 0404142def test_central_regime_saturates_when_capacity_below_load():43    low = simulate(Params(N=200, regime="central", seed=0, admin_capacity_ratio=0.25))44    high = simulate(Params(N=200, regime="central", seed=0, admin_capacity_ratio=4.0))45    assert low["success_rate"] < high["success_rate"] and low["fail_latency_share"] > high["fail_latency_share"]46
Files · 8f19ce36212f3d403648b32eec919c5eb93586c9
Menu

Theme