Source code for mcframework.utils

"""
mcframework.utils
=====================
Utility functions for critical values and CI selection.

This module provides z/t critical values and a tiny helper, :func:`autocrit`,
that chooses between normal and t criticals in a reproducible way.
"""

from __future__ import annotations

from scipy.stats import norm, t  # type: ignore[import-untyped]

__all__ = ["z_crit", "t_crit", "autocrit"]


[docs] def _validate_confidence(confidence: float) -> None: r""" Validate the confidence level. Parameters ---------- confidence : float Confidence level to validate. Raises ------ ValueError If ``confidence`` is not in the open interval ``(0, 1)``. """ if not 0.0 < confidence < 1.0: raise ValueError("confidence must be in the open interval (0, 1)")
[docs] def z_crit(confidence: float) -> float: r""" Two-sided normal critical value :math:`z_{\alpha/2}`. For a given confidence level :math:`1-\alpha`, this returns the upper :math:`1-\alpha/2` quantile of the standard normal, i.e. :math:`z_{\alpha/2} = \Phi^{-1}(1-\alpha/2)`. Parameters ---------- confidence : float Confidence level in ``(0, 1)`` (e.g. ``0.95``). Returns ------- float :math:`z_{\alpha/2}`. Raises ------ ValueError If ``confidence`` is not in ``(0, 1)``. Examples -------- >>> round(z_crit(0.95), 2) 1.96 """ _validate_confidence(confidence) return float(norm.ppf(1.0 - (1.0 - confidence) / 2.0))
[docs] def t_crit(confidence: float, df: int) -> float: r""" Two-sided Student t critical value :math:`t_{\alpha/2,\;\mathrm{df}}`. Parameters ---------- confidence : float Confidence level in ``(0, 1)``. df : int Degrees of freedom (``\mathrm{df} \ge 1``), typically ``n-1``. Returns ------- float :math:`t_{\alpha/2,\;\mathrm{df}}\ `- the upper :math:`1-\alpha/2` quantile of :math:`t_{\mathrm{df}}`. Raises ------ ValueError If ``confidence`` is not in ``(0, 1)`` or ``df < 1``. Examples -------- >>> round(t_crit(0.95, df=9), 3) 2.262 """ _validate_confidence(confidence) if df < 1: raise ValueError("df must be >= 1") return float(t.ppf(1.0 - (1.0 - confidence) / 2.0, df))
[docs] def autocrit(confidence: float, n: int, method: str = "auto") -> tuple[float, str]: r""" Select a critical value (z or t) for two-sided CIs. Chooses between :func:`z_crit` and :func:`t_crit` based on the requested ``method`` and the sample size ``n``: * ``method="z"`` – always use normal criticals. * ``method="t"`` – always use Student t with ``\mathrm{df} = \max(1, n-1)``. * ``method="auto"`` – use z if ``n \ge 30``, else t. Parameters ---------- confidence : float Confidence level in ``(0, 1)``. n : int Sample size used to choose the rule-of-thumb cutoff for ``"auto"``. method : {"auto", "z", "t"}, default "auto" Selection policy. Returns ------- (float, str) Pair ``(crit, kind)`` where ``crit`` is the critical value and ``kind`` is the string ``"z"`` or ``"t"`` indicating the choice. Raises ------ ValueError If ``confidence`` is invalid or ``method`` is not one of ``{"auto","z","t"}``. Notes ----- The returned critical is intended for two-sided intervals of the form .. math:: \bar X \pm c \,\frac{s}{\sqrt{n}}, where :math:`c` is either :math:`z_{\alpha/2}` or :math:`t_{\alpha/2,\;\mathrm{df}}` with :math:`\mathrm{df}=\max(1, n-1)`. See Also -------- mcframework.stats_engine.ci_mean : Uses this selector to build mean CIs. Examples -------- >>> c, kind = autocrit(0.95, n=20, method="auto") >>> kind 't' >>> round(c, 2) 2.09 >>> c, kind = autocrit(0.95, n=50, method="auto") >>> kind 'z' >>> round(c, 2) 1.96 """ _validate_confidence(confidence) if method not in ("auto", "z", "t"): raise ValueError("method must be 'auto', 'z', or 't'") if method == "z" or (method == "auto" and n >= 30): return z_crit(confidence), "z" return t_crit(confidence, max(1, n - 1)), "t"