pystatistics 3.2.0__tar.gz → 3.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pystatistics-3.3.0/.release/UNRELEASED.md +30 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/CHANGELOG.md +24 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/PKG-INFO +36 -1
- {pystatistics-3.2.0 → pystatistics-3.3.0}/README.md +35 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pyproject.toml +1 -1
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/__init__.py +3 -1
- pystatistics-3.3.0/pystatistics/mice/__init__.py +29 -0
- pystatistics-3.3.0/pystatistics/mice/_chain.py +113 -0
- pystatistics-3.3.0/pystatistics/mice/_rng.py +88 -0
- pystatistics-3.3.0/pystatistics/mice/_visit.py +58 -0
- pystatistics-3.3.0/pystatistics/mice/backends/__init__.py +1 -0
- pystatistics-3.3.0/pystatistics/mice/backends/cpu.py +92 -0
- pystatistics-3.3.0/pystatistics/mice/datasets.py +116 -0
- pystatistics-3.3.0/pystatistics/mice/design.py +373 -0
- pystatistics-3.3.0/pystatistics/mice/methods/__init__.py +27 -0
- pystatistics-3.3.0/pystatistics/mice/methods/_linreg.py +133 -0
- pystatistics-3.3.0/pystatistics/mice/methods/base.py +57 -0
- pystatistics-3.3.0/pystatistics/mice/methods/norm.py +42 -0
- pystatistics-3.3.0/pystatistics/mice/methods/pmm.py +86 -0
- pystatistics-3.3.0/pystatistics/mice/methods/registry.py +59 -0
- pystatistics-3.3.0/pystatistics/mice/pooling.py +181 -0
- pystatistics-3.3.0/pystatistics/mice/solution.py +156 -0
- pystatistics-3.3.0/pystatistics/mice/solvers.py +154 -0
- pystatistics-3.3.0/tests/mice/references/generate_mice_fixtures.R +104 -0
- pystatistics-3.3.0/tests/mice/references/mice_reference.json +78 -0
- pystatistics-3.3.0/tests/mice/references/mice_validation_complete.csv +201 -0
- pystatistics-3.3.0/tests/mice/references/mice_validation_data.csv +201 -0
- pystatistics-3.3.0/tests/mice/test_datasets.py +68 -0
- pystatistics-3.3.0/tests/mice/test_design.py +128 -0
- pystatistics-3.3.0/tests/mice/test_methods.py +141 -0
- pystatistics-3.3.0/tests/mice/test_mice.py +149 -0
- pystatistics-3.3.0/tests/mice/test_pooling.py +142 -0
- pystatistics-3.3.0/tests/mice/test_r_validation.py +152 -0
- pystatistics-3.3.0/tests/mice/test_rng.py +76 -0
- pystatistics-3.3.0/tests/mice/test_visit.py +34 -0
- pystatistics-3.3.0/tests/timeseries/__init__.py +0 -0
- pystatistics-3.2.0/.release/UNRELEASED.md +0 -42
- {pystatistics-3.2.0 → pystatistics-3.3.0}/.github/workflows/publish.yml +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/.github/workflows/trigger-docs-rebuild.yml +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/.gitignore +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/.release/CHECKLIST.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/.release/release.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/CLAUDE.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/LICENSE +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/benchmarks/mvnmle_bench.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/DESIGN.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/Forge.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/GPU_BACKEND_NOTES.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/Makefile +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/PYSTATSBIO_CONTEXT.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/ROADMAP.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/_static/custom.css +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/anova.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/conf.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/core.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/descriptive.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/gam.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/hypothesis.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/index.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/mixed.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/montecarlo.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/multinomial.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/multivariate.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/mvnmle.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/ordinal.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/regression.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/survival.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/docs/timeseries.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/GPU_BACKEND_CONVENTION.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_contrasts.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_levene.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_posthoc.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_repeated.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/_ss.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/anova/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/capabilities.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/device.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/batched.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/cholesky.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/determinant.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/qr.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/solve.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/svd.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/optimization/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/optimization/convergence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/precision.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/timing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/tolerances.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/compute/torch_interop.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/datasource.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/encoding.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/exceptions.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/protocols.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/result.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/core/validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/_missing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/_quantile_types.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/descriptive/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_basis.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_gam.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_gcv.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/_smooth.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/backends/_gpu_family.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/backends/gpu_pirls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/gam/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_design_factories.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_p_adjust.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_chisq_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_fisher_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_ks_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_prop_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_t_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_var_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_wilcox_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/hypothesis/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_deviance.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_pirls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_pls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_random_effects.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/_satterthwaite.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mixed/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_ci.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_influence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/montecarlo/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/backends/gpu_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multinomial/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/_factor.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/_pca.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/_rotation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/multivariate/backends/gpu_pca.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_monotone.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/base.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/gpu_fp32.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/gpu_fp64.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/parameterizations.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_utils.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_np.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_patterns.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_torch.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_squarem.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/em.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/datasets.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/mcar_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/patterns.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/mvnmle/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/backends/gpu_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/ordinal/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/py.typed +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/_formatting.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/_linear.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/_nb_theta.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/backends/cpu_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/backends/gpu_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/families.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/regression/terms.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/_cox.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/_discrete.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/_km.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/_logrank.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/survival/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_acf.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_batch.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_factored.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_forecast.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_kalman.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_order.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_decomposition.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_differencing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_forecast.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_models.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_stationarity.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/_whittle.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/whittle_batch_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/whittle_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_contrasts.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_factorial.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_levene.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_oneway.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_posthoc.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/anova/test_repeated_measures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/benchmark_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/core/test_datasource.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/core/test_exceptions.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/core/test_result.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/core/test_torch_interop.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/core/test_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_cor.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_cov.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_describe.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_missing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_moments.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_quantile.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/descriptive/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_ancova_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_ancova_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_bonferroni_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_bonferroni_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_eta_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_eta_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_levene_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_levene_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_unbalanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_unbalanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_mixed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_mixed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_within_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_within_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_tukey_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_tukey_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_unbalanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_unbalanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/different_scales.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/different_scales_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/different_scales_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_anova_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_descriptive_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_glm_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_hypothesis_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_mixed_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_montecarlo_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/generate_survival_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/high_noise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/high_noise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/high_noise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_2x2_yates_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_2x2_yates_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_3x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_3x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_unequal_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_unequal_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_less_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_less_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_3x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_3x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_onesample_norm_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_onesample_norm_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_twosample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_twosample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_onesample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_onesample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_twosample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_twosample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_onesample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_onesample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_paired_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_paired_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_pooled_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_pooled_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_welch_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_welch_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_var_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_var_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_ranksum_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_ranksum_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_signed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_signed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_90_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_90_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_normal_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_normal_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_skewed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_skewed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_ordinary_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_ordinary_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_median_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_median_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_variance_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_variance_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_greater_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_greater_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_not_significant_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_not_significant_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_significant_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_significant_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/glmm_binomial.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/glmm_poisson.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_crossed.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_intercept.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_ml.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_no_effect.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_slope.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/mixed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/mixed/mixed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/near_square.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/near_square_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/near_square_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_anova_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_descriptive_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_glm_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_hypothesis_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_mixed_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_montecarlo_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_survival_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_r_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/run_validation.sh +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/small_noise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/small_noise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/small_noise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_breslow_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_breslow_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_single_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_single_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_two_cov_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_two_cov_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_heavy_cens_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_heavy_cens_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_loglog_ci_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_loglog_ci_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_no_cens_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_no_cens_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_plain_ci_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_plain_ci_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_peto_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_peto_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_three_group_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_three_group_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_two_group_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_two_group_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/fixtures/validate_against_r.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/gam/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/gam/test_gam.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_chisq_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_design_split.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_fisher_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_ks_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_p_adjust.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_prop_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_t_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_var_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/hypothesis/test_wilcox_test.py +0 -0
- {pystatistics-3.2.0/tests/mixed → pystatistics-3.3.0/tests/mice}/__init__.py +0 -0
- {pystatistics-3.2.0/tests/montecarlo → pystatistics-3.3.0/tests/mixed}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_glmm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_crossed.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_intercept.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_nested.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_slope.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_pls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_random_effects.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mixed/test_satterthwaite.py +0 -0
- {pystatistics-3.2.0/tests/multinomial → pystatistics-3.3.0/tests/montecarlo}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_batched_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_boot_ci.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_bootstrap.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_influence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_permutation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/montecarlo/test_r_validation.py +0 -0
- {pystatistics-3.2.0/tests/multivariate → pystatistics-3.3.0/tests/multinomial}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/multinomial/test_multinom.py +0 -0
- {pystatistics-3.2.0/tests/ordinal → pystatistics-3.3.0/tests/multivariate}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/multivariate/test_multivariate.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/apple_em_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/apple_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/generate_em_fixtures.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_apple.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_complete.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_extreme.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_missvals.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_simple_mcar.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_summary.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/missvals_em_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/missvals_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/references/small_test_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_em.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_mcar.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_mlest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_monotone.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_no_silent_fallback.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/mvnmle/test_squarem.py +0 -0
- {pystatistics-3.2.0/tests/survival → pystatistics-3.3.0/tests/ordinal}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/ordinal/test_ordinal.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/benchmark.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/benchmark.r +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_gamma_nb.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_glm_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_glm_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_module_split.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_stress_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_terms.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/regression/test_terms_gpu.py +0 -0
- {pystatistics-3.2.0/tests/timeseries → pystatistics-3.3.0/tests/survival}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_coxph.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_discrete_time.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_kaplan_meier.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_logrank.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/survival/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/test_code_quality.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/timeseries/test_acf_stationarity.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/timeseries/test_arima.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/timeseries/test_decomposition.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.3.0}/tests/timeseries/test_ets.py +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Unreleased Changes
|
|
2
|
+
|
|
3
|
+
> This file tracks all changes since the last stable release.
|
|
4
|
+
> Updated by whoever makes a change, on whatever machine.
|
|
5
|
+
> Synced via git so all sessions (Mac, Linux, etc.) see the same state.
|
|
6
|
+
>
|
|
7
|
+
> When ready to release, run: `python .release/release.py --status`
|
|
8
|
+
> and follow the manual release flow in the script docstring.
|
|
9
|
+
|
|
10
|
+
## Changes
|
|
11
|
+
|
|
12
|
+
- New `mice` module: Multiple Imputation by Chained Equations for multivariate
|
|
13
|
+
missing data. `pystatistics.mice.mice(data, m=5, maxit=5, method='pmm',
|
|
14
|
+
seed=...)` iteratively imputes each incomplete numeric column from the others
|
|
15
|
+
and returns `m` completed datasets (`MICESolution`). Numeric methods `pmm`
|
|
16
|
+
(predictive mean matching, the R default) and `norm` (Bayesian linear
|
|
17
|
+
regression) are included, with R-faithful defaults (`m=5`, `maxit=5`, 5 PMM
|
|
18
|
+
donors, left-to-right visit sequence). Imputation is fully deterministic given
|
|
19
|
+
`seed` (required), with independent per-chain RNG streams.
|
|
20
|
+
- New `pystatistics.mice.pool`: Rubin's-rules pooling of an analysis across the
|
|
21
|
+
`m` completed datasets, with Barnard-Rubin degrees of freedom and the standard
|
|
22
|
+
diagnostics (within/between/total variance, relative increase in variance,
|
|
23
|
+
lambda, fraction of missing information) and confidence intervals.
|
|
24
|
+
- Validated distributionally against R's `mice` 3.19.0: imputed-value
|
|
25
|
+
distributions (mean, spread, quantiles) and Rubin's-rules pooled regression
|
|
26
|
+
output match R on a shared incomplete dataset. Reference fixtures and the
|
|
27
|
+
pinned generation script live in `tests/mice/references/`.
|
|
28
|
+
- CPU implementation only in this release. The module is structured (method
|
|
29
|
+
registry, single backend entrypoint, per-column type metadata) so GPU
|
|
30
|
+
acceleration and categorical methods can be added without restructuring.
|
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.3.0
|
|
4
|
+
|
|
5
|
+
Multiple imputation by chained equations (MICE) for multivariate missing data.
|
|
6
|
+
|
|
7
|
+
- **New `mice` module.** `pystatistics.mice.mice(data, m=5, maxit=5,
|
|
8
|
+
method='pmm', seed=...)` imputes a numeric data matrix that contains missing
|
|
9
|
+
values (NaN) by iteratively modelling each incomplete column from the others,
|
|
10
|
+
and returns `m` completed datasets. Two methods are available: `'pmm'`
|
|
11
|
+
(predictive mean matching — the default, which imputes by copying observed
|
|
12
|
+
donor values) and `'norm'` (Bayesian linear regression). Defaults follow R's
|
|
13
|
+
`mice` package (`m=5`, `maxit=5`, 5 PMM donors, left-to-right visit order).
|
|
14
|
+
- **Reproducible by construction.** A `seed` is required; given the same seed,
|
|
15
|
+
imputations are identical across runs and machines. Each of the `m` chains
|
|
16
|
+
draws from its own independent random stream.
|
|
17
|
+
- **Rubin's-rules pooling.** `pystatistics.mice.pool(estimates, variances)`
|
|
18
|
+
combines an analysis fitted on each completed dataset into a single inference,
|
|
19
|
+
with Barnard–Rubin degrees of freedom, confidence intervals, and the usual
|
|
20
|
+
diagnostics (within/between/total variance, relative increase in variance,
|
|
21
|
+
fraction of missing information).
|
|
22
|
+
- **Validated against R.** Imputed-value distributions and pooled regression
|
|
23
|
+
output are checked against R's `mice` on a shared dataset.
|
|
24
|
+
- This release covers numeric columns on the CPU. Categorical-column methods
|
|
25
|
+
and GPU acceleration are planned for future releases.
|
|
26
|
+
|
|
3
27
|
## 3.2.0
|
|
4
28
|
|
|
5
29
|
Apple Silicon (MPS) GPU support for the FP32 backends, with honest,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystatistics
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.0
|
|
4
4
|
Summary: GPU-accelerated statistical computing for Python
|
|
5
5
|
Project-URL: Homepage, https://sgcx.org/technology/pystatistics/
|
|
6
6
|
Project-URL: Documentation, https://sgcx.org/docs/pystatistics/
|
|
@@ -86,6 +86,7 @@ PyStatistics maintains two parallel computational paths with distinct goals:
|
|
|
86
86
|
| `multivariate/` | Complete | PCA and maximum likelihood factor analysis with varimax/promax rotation |
|
|
87
87
|
| `timeseries/` | Complete | ACF, PACF, ADF, KPSS, ETS, ARIMA, SARIMA, auto_arima, decompose, STL |
|
|
88
88
|
| `gam/` | Complete | Generalized additive models with penalized regression splines matching R mgcv::gam |
|
|
89
|
+
| `mice/` | Numeric (CPU) | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice |
|
|
89
90
|
|
|
90
91
|
See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed scope, GPU applicability, and implementation priority for each module.
|
|
91
92
|
|
|
@@ -373,6 +374,27 @@ y = np.sin(x) + np.random.randn(200) * 0.3
|
|
|
373
374
|
result = gam(y, smooths=[s('x1')], smooth_data={'x1': x})
|
|
374
375
|
print(result.edf, result.gcv)
|
|
375
376
|
print(result.summary())
|
|
377
|
+
|
|
378
|
+
# --- Multiple imputation (MICE) ---
|
|
379
|
+
from pystatistics.mice import mice, pool
|
|
380
|
+
|
|
381
|
+
# data is an (n, p) array with np.nan marking missing values.
|
|
382
|
+
# Predictive mean matching (R default) for numeric columns; seed is required
|
|
383
|
+
# so the imputation is fully reproducible.
|
|
384
|
+
imp = mice(data, m=5, maxit=5, method='pmm', seed=0)
|
|
385
|
+
completed = imp.completed_datasets() # list of 5 completed (n, p) arrays
|
|
386
|
+
|
|
387
|
+
# Fit your analysis on each completed dataset, then combine with Rubin's rules:
|
|
388
|
+
estimates, variances = [], []
|
|
389
|
+
for d in completed:
|
|
390
|
+
X = np.column_stack([np.ones(len(d)), d[:, 1]])
|
|
391
|
+
beta, *_ = np.linalg.lstsq(X, d[:, 0], rcond=None)
|
|
392
|
+
resid = d[:, 0] - X @ beta
|
|
393
|
+
cov = (resid @ resid / (len(d) - 2)) * np.linalg.inv(X.T @ X)
|
|
394
|
+
estimates.append(beta[1]); variances.append(cov[1, 1])
|
|
395
|
+
|
|
396
|
+
pooled = pool(estimates, variances, dfcom=len(data) - 2)
|
|
397
|
+
print(pooled.estimate, pooled.se, pooled.ci_low, pooled.ci_high, pooled.fmi)
|
|
376
398
|
```
|
|
377
399
|
|
|
378
400
|
## Installation
|
|
@@ -391,6 +413,19 @@ pip install pystatistics[dev]
|
|
|
391
413
|
|
|
392
414
|
## What's New
|
|
393
415
|
|
|
416
|
+
### 3.3.0 — Multiple imputation (MICE)
|
|
417
|
+
|
|
418
|
+
- New `mice` module: multiple imputation by chained equations for numeric data
|
|
419
|
+
with missing values. `mice(data, m=5, method='pmm', seed=...)` returns `m`
|
|
420
|
+
completed datasets, using predictive mean matching (the R default) or
|
|
421
|
+
Bayesian linear regression (`method='norm'`). Defaults follow R's `mice`.
|
|
422
|
+
- Imputation is fully reproducible — `seed` is required, and each chain uses an
|
|
423
|
+
independent random stream.
|
|
424
|
+
- `pool(estimates, variances)` combines per-dataset analyses with Rubin's rules
|
|
425
|
+
(Barnard–Rubin degrees of freedom, confidence intervals, fraction of missing
|
|
426
|
+
information).
|
|
427
|
+
- Numeric columns on the CPU in this release; validated against R's `mice`.
|
|
428
|
+
|
|
394
429
|
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
395
430
|
|
|
396
431
|
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
@@ -39,6 +39,7 @@ PyStatistics maintains two parallel computational paths with distinct goals:
|
|
|
39
39
|
| `multivariate/` | Complete | PCA and maximum likelihood factor analysis with varimax/promax rotation |
|
|
40
40
|
| `timeseries/` | Complete | ACF, PACF, ADF, KPSS, ETS, ARIMA, SARIMA, auto_arima, decompose, STL |
|
|
41
41
|
| `gam/` | Complete | Generalized additive models with penalized regression splines matching R mgcv::gam |
|
|
42
|
+
| `mice/` | Numeric (CPU) | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice |
|
|
42
43
|
|
|
43
44
|
See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed scope, GPU applicability, and implementation priority for each module.
|
|
44
45
|
|
|
@@ -326,6 +327,27 @@ y = np.sin(x) + np.random.randn(200) * 0.3
|
|
|
326
327
|
result = gam(y, smooths=[s('x1')], smooth_data={'x1': x})
|
|
327
328
|
print(result.edf, result.gcv)
|
|
328
329
|
print(result.summary())
|
|
330
|
+
|
|
331
|
+
# --- Multiple imputation (MICE) ---
|
|
332
|
+
from pystatistics.mice import mice, pool
|
|
333
|
+
|
|
334
|
+
# data is an (n, p) array with np.nan marking missing values.
|
|
335
|
+
# Predictive mean matching (R default) for numeric columns; seed is required
|
|
336
|
+
# so the imputation is fully reproducible.
|
|
337
|
+
imp = mice(data, m=5, maxit=5, method='pmm', seed=0)
|
|
338
|
+
completed = imp.completed_datasets() # list of 5 completed (n, p) arrays
|
|
339
|
+
|
|
340
|
+
# Fit your analysis on each completed dataset, then combine with Rubin's rules:
|
|
341
|
+
estimates, variances = [], []
|
|
342
|
+
for d in completed:
|
|
343
|
+
X = np.column_stack([np.ones(len(d)), d[:, 1]])
|
|
344
|
+
beta, *_ = np.linalg.lstsq(X, d[:, 0], rcond=None)
|
|
345
|
+
resid = d[:, 0] - X @ beta
|
|
346
|
+
cov = (resid @ resid / (len(d) - 2)) * np.linalg.inv(X.T @ X)
|
|
347
|
+
estimates.append(beta[1]); variances.append(cov[1, 1])
|
|
348
|
+
|
|
349
|
+
pooled = pool(estimates, variances, dfcom=len(data) - 2)
|
|
350
|
+
print(pooled.estimate, pooled.se, pooled.ci_low, pooled.ci_high, pooled.fmi)
|
|
329
351
|
```
|
|
330
352
|
|
|
331
353
|
## Installation
|
|
@@ -344,6 +366,19 @@ pip install pystatistics[dev]
|
|
|
344
366
|
|
|
345
367
|
## What's New
|
|
346
368
|
|
|
369
|
+
### 3.3.0 — Multiple imputation (MICE)
|
|
370
|
+
|
|
371
|
+
- New `mice` module: multiple imputation by chained equations for numeric data
|
|
372
|
+
with missing values. `mice(data, m=5, method='pmm', seed=...)` returns `m`
|
|
373
|
+
completed datasets, using predictive mean matching (the R default) or
|
|
374
|
+
Bayesian linear regression (`method='norm'`). Defaults follow R's `mice`.
|
|
375
|
+
- Imputation is fully reproducible — `seed` is required, and each chain uses an
|
|
376
|
+
independent random stream.
|
|
377
|
+
- `pool(estimates, variances)` combines per-dataset analyses with Rubin's rules
|
|
378
|
+
(Barnard–Rubin degrees of freedom, confidence intervals, fraction of missing
|
|
379
|
+
information).
|
|
380
|
+
- Numeric columns on the CPU in this release; validated against R's `mice`.
|
|
381
|
+
|
|
347
382
|
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
348
383
|
|
|
349
384
|
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
@@ -16,7 +16,7 @@ Usage:
|
|
|
16
16
|
result = fit(design)
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
-
__version__ = "3.
|
|
19
|
+
__version__ = "3.3.0"
|
|
20
20
|
__author__ = "Hai-Shuo"
|
|
21
21
|
__email__ = "contact@sgcx.org"
|
|
22
22
|
|
|
@@ -34,6 +34,7 @@ from pystatistics import ordinal
|
|
|
34
34
|
from pystatistics import multivariate
|
|
35
35
|
from pystatistics import timeseries
|
|
36
36
|
from pystatistics import gam
|
|
37
|
+
from pystatistics import mice
|
|
37
38
|
|
|
38
39
|
__all__ = [
|
|
39
40
|
"__version__",
|
|
@@ -51,4 +52,5 @@ __all__ = [
|
|
|
51
52
|
"multivariate",
|
|
52
53
|
"timeseries",
|
|
53
54
|
"gam",
|
|
55
|
+
"mice",
|
|
54
56
|
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MICE — Multiple Imputation by Chained Equations.
|
|
3
|
+
|
|
4
|
+
Iteratively impute each incomplete column from the others until the chain
|
|
5
|
+
stabilises, producing ``m`` completed datasets, then combine analyses across
|
|
6
|
+
them with Rubin's rules. R-pegged: numeric defaults follow R's ``mice`` package
|
|
7
|
+
(predictive mean matching for numeric columns).
|
|
8
|
+
|
|
9
|
+
Public API (Stage 1, CPU, numeric columns):
|
|
10
|
+
|
|
11
|
+
>>> from pystatistics.mice import mice, pool
|
|
12
|
+
>>> imp = mice(data, m=5, method='pmm', seed=0)
|
|
13
|
+
>>> completed = imp.completed_datasets() # list of m arrays
|
|
14
|
+
|
|
15
|
+
Stage 1 supports numeric columns only; categorical methods are planned.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from pystatistics.mice.design import MICEDesign
|
|
19
|
+
from pystatistics.mice.pooling import PooledResult, pool
|
|
20
|
+
from pystatistics.mice.solution import MICESolution
|
|
21
|
+
from pystatistics.mice.solvers import mice
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"MICEDesign",
|
|
25
|
+
"MICESolution",
|
|
26
|
+
"PooledResult",
|
|
27
|
+
"mice",
|
|
28
|
+
"pool",
|
|
29
|
+
]
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""
|
|
2
|
+
The chained-equations sweep — one imputation chain.
|
|
3
|
+
|
|
4
|
+
A single chain produces one completed dataset:
|
|
5
|
+
|
|
6
|
+
1. *Initialise* every missing cell by a random draw from the observed values of
|
|
7
|
+
its own column (R mice's default start), so all predictor columns are fully
|
|
8
|
+
populated from iteration 1.
|
|
9
|
+
2. *Sweep* ``maxit`` times. In each iteration, visit the incomplete columns in
|
|
10
|
+
the visit sequence; for each, fit the column's assigned method on the rows
|
|
11
|
+
where it is observed (using all other columns as predictors) and overwrite
|
|
12
|
+
its missing cells with fresh draws.
|
|
13
|
+
3. Record, per iteration and per incomplete column, the mean and variance of
|
|
14
|
+
the imputed cells — the trace MICE convergence diagnostics are read from.
|
|
15
|
+
|
|
16
|
+
This module owns orchestration only. The per-variable statistical work lives
|
|
17
|
+
behind the :class:`ImputationMethod` protocol, so the sweep never hard-codes a
|
|
18
|
+
method and a GPU backend can swap in batched method implementations without
|
|
19
|
+
touching this control flow.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
from dataclasses import dataclass
|
|
25
|
+
|
|
26
|
+
import numpy as np
|
|
27
|
+
|
|
28
|
+
from pystatistics.mice.design import MICEDesign
|
|
29
|
+
from pystatistics.mice.methods import get_method
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(frozen=True)
|
|
33
|
+
class ChainResult:
|
|
34
|
+
"""Output of one chain: completed data plus convergence traces."""
|
|
35
|
+
|
|
36
|
+
completed: np.ndarray # (n, p) — no NaN
|
|
37
|
+
chain_mean: np.ndarray # (maxit, n_incomplete)
|
|
38
|
+
chain_var: np.ndarray # (maxit, n_incomplete)
|
|
39
|
+
incomplete_columns: tuple[int, ...]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def run_chain(
|
|
43
|
+
design: MICEDesign,
|
|
44
|
+
rng: np.random.Generator,
|
|
45
|
+
maxit: int,
|
|
46
|
+
visit_sequence: tuple[int, ...],
|
|
47
|
+
) -> ChainResult:
|
|
48
|
+
"""Run one chained-equations chain. See module docstring."""
|
|
49
|
+
data = design.data.copy()
|
|
50
|
+
mask = design.missing_mask
|
|
51
|
+
p = design.p
|
|
52
|
+
incomplete = design.incomplete_columns
|
|
53
|
+
|
|
54
|
+
_initialise(data, mask, incomplete, rng)
|
|
55
|
+
|
|
56
|
+
chain_mean = np.empty((maxit, len(incomplete)), dtype=np.float64)
|
|
57
|
+
chain_var = np.empty((maxit, len(incomplete)), dtype=np.float64)
|
|
58
|
+
incomplete_pos = {j: k for k, j in enumerate(incomplete)}
|
|
59
|
+
|
|
60
|
+
for it in range(maxit):
|
|
61
|
+
for j in visit_sequence:
|
|
62
|
+
mis_rows = mask[:, j]
|
|
63
|
+
obs_rows = ~mis_rows
|
|
64
|
+
|
|
65
|
+
predictors = _predictor_columns(data, j, p)
|
|
66
|
+
X_obs = predictors[obs_rows]
|
|
67
|
+
X_mis = predictors[mis_rows]
|
|
68
|
+
y_obs = data[obs_rows, j]
|
|
69
|
+
|
|
70
|
+
method = get_method(design.method_for(j))
|
|
71
|
+
imputed = method.impute(y_obs, X_obs, X_mis, rng)
|
|
72
|
+
data[mis_rows, j] = imputed
|
|
73
|
+
|
|
74
|
+
# Trace: summarise this iteration's imputed cells per incomplete column.
|
|
75
|
+
for j in incomplete:
|
|
76
|
+
cells = data[mask[:, j], j]
|
|
77
|
+
k = incomplete_pos[j]
|
|
78
|
+
chain_mean[it, k] = float(np.mean(cells))
|
|
79
|
+
chain_var[it, k] = float(np.var(cells))
|
|
80
|
+
|
|
81
|
+
return ChainResult(
|
|
82
|
+
completed=data,
|
|
83
|
+
chain_mean=chain_mean,
|
|
84
|
+
chain_var=chain_var,
|
|
85
|
+
incomplete_columns=incomplete,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _initialise(
|
|
90
|
+
data: np.ndarray,
|
|
91
|
+
mask: np.ndarray,
|
|
92
|
+
incomplete: tuple[int, ...],
|
|
93
|
+
rng: np.random.Generator,
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Fill missing cells by sampling (with replacement) from observed values of
|
|
96
|
+
the same column. Mutates ``data`` in place."""
|
|
97
|
+
for j in incomplete:
|
|
98
|
+
mis_rows = mask[:, j]
|
|
99
|
+
observed = data[~mis_rows, j]
|
|
100
|
+
n_missing = int(np.count_nonzero(mis_rows))
|
|
101
|
+
data[mis_rows, j] = rng.choice(observed, size=n_missing, replace=True)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def _predictor_columns(data: np.ndarray, j: int, p: int) -> np.ndarray:
|
|
105
|
+
"""All columns except ``j`` (the current target), as a 2D predictor matrix.
|
|
106
|
+
|
|
107
|
+
Columns are fully populated at this point (initialised on entry, kept
|
|
108
|
+
complete by every visit), so the returned matrix is finite. Fancy-indexing
|
|
109
|
+
with a list always yields a 2D matrix, including the single-predictor
|
|
110
|
+
(p == 2) case.
|
|
111
|
+
"""
|
|
112
|
+
cols = [c for c in range(p) if c != j]
|
|
113
|
+
return data[:, cols]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Deterministic random-number management for MICE.
|
|
3
|
+
|
|
4
|
+
Multiple imputation is *intrinsically* stochastic: each completed dataset is a
|
|
5
|
+
draw from the posterior predictive distribution of the missing data. That
|
|
6
|
+
randomness is the method, not a bug. What we owe the user (CLAUDE.md Rule 6) is
|
|
7
|
+
that the randomness be fully controlled by an explicit, injectable seed, and
|
|
8
|
+
isolated behind this module so the rest of the system stays deterministic and
|
|
9
|
+
testable.
|
|
10
|
+
|
|
11
|
+
# NON-DETERMINISTIC: every function here produces or wraps a pseudo-random
|
|
12
|
+
# stream. The non-determinism is real but is *seeded* — given the same seed,
|
|
13
|
+
# every downstream draw is bit-for-bit reproducible across runs and machines.
|
|
14
|
+
# No other module in `mice` is permitted to call into numpy.random directly;
|
|
15
|
+
# all randomness must flow through the Generators handed out here.
|
|
16
|
+
|
|
17
|
+
We deliberately do NOT try to reproduce R's Mersenne-Twister stream. MICE is
|
|
18
|
+
validated against R *distributionally* (same defaults, same algorithm, matching
|
|
19
|
+
statistical behaviour across seeds), not by RNG-stream parity — see
|
|
20
|
+
``tests/mice/references/generate_mice_fixtures.R``.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
27
|
+
from pystatistics.core.exceptions import ValidationError
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def make_rng(seed: int) -> np.random.Generator:
|
|
31
|
+
"""Construct a NumPy Generator from an integer seed.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
seed : int
|
|
36
|
+
Non-negative integer seed. Required (not optional): reproducibility is
|
|
37
|
+
a first-class guarantee of this module, so there is no "unseeded" path.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
numpy.random.Generator
|
|
42
|
+
"""
|
|
43
|
+
_validate_seed(seed)
|
|
44
|
+
return np.random.default_rng(seed)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def spawn_streams(seed: int, m: int) -> list[np.random.Generator]:
|
|
48
|
+
"""Spawn ``m`` independent, reproducible Generators from one master seed.
|
|
49
|
+
|
|
50
|
+
Each of the ``m`` imputation chains needs its own random stream so the
|
|
51
|
+
chains are statistically independent, yet the whole set must be reproducible
|
|
52
|
+
from the single user-facing ``seed``. ``numpy.random.SeedSequence`` provides
|
|
53
|
+
exactly this: deterministic, high-quality spawning of independent substreams.
|
|
54
|
+
|
|
55
|
+
The substreams do not depend on the order in which they are *consumed*, only
|
|
56
|
+
on ``(seed, m)`` and their index — so a future GPU backend that runs the
|
|
57
|
+
chains concurrently gets identical draws to the sequential CPU backend.
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
seed : int
|
|
62
|
+
Master seed.
|
|
63
|
+
m : int
|
|
64
|
+
Number of independent streams (one per imputation). Must be >= 1.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
list of numpy.random.Generator
|
|
69
|
+
Length ``m``.
|
|
70
|
+
"""
|
|
71
|
+
_validate_seed(seed)
|
|
72
|
+
if not isinstance(m, (int, np.integer)) or isinstance(m, bool):
|
|
73
|
+
raise ValidationError(f"m must be an integer, got {type(m).__name__}")
|
|
74
|
+
if m < 1:
|
|
75
|
+
raise ValidationError(f"m must be >= 1, got {m}")
|
|
76
|
+
|
|
77
|
+
child_seeds = np.random.SeedSequence(int(seed)).spawn(int(m))
|
|
78
|
+
return [np.random.default_rng(cs) for cs in child_seeds]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _validate_seed(seed: int) -> None:
|
|
82
|
+
"""Fail loud on an invalid seed (Rule 1)."""
|
|
83
|
+
if isinstance(seed, bool) or not isinstance(seed, (int, np.integer)):
|
|
84
|
+
raise ValidationError(
|
|
85
|
+
f"seed must be a non-negative integer, got {type(seed).__name__}"
|
|
86
|
+
)
|
|
87
|
+
if seed < 0:
|
|
88
|
+
raise ValidationError(f"seed must be non-negative, got {seed}")
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Visit-sequence construction for the chained-equations sweep.
|
|
3
|
+
|
|
4
|
+
The visit sequence is the order in which incomplete columns are imputed within
|
|
5
|
+
each iteration. R mice's default ("roman") visits the columns that contain
|
|
6
|
+
missing data in left-to-right column order, which is what Stage 1 implements.
|
|
7
|
+
|
|
8
|
+
Isolated in its own module because R supports several sequence policies
|
|
9
|
+
(monotone, reverse, custom orderings); keeping the policy here means adding one
|
|
10
|
+
later does not touch the sweep loop.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from pystatistics.core.exceptions import ValidationError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def default_visit_sequence(incomplete_columns: tuple[int, ...]) -> tuple[int, ...]:
|
|
19
|
+
"""R-default ("roman"): incomplete columns in ascending index order."""
|
|
20
|
+
return tuple(sorted(incomplete_columns))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def resolve_visit_sequence(
|
|
24
|
+
incomplete_columns: tuple[int, ...],
|
|
25
|
+
override,
|
|
26
|
+
) -> tuple[int, ...]:
|
|
27
|
+
"""Resolve the visit sequence, validating any user override.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
incomplete_columns : tuple of int
|
|
32
|
+
Column indices that actually contain missing values.
|
|
33
|
+
override : sequence of int or None
|
|
34
|
+
Explicit visit order. If None, uses the R default. If given, every
|
|
35
|
+
entry must be an incomplete column index; columns may be repeated
|
|
36
|
+
(legal in MICE — a variable can be visited more than once per
|
|
37
|
+
iteration) but every incomplete column must appear at least once so no
|
|
38
|
+
missing values are left un-imputed.
|
|
39
|
+
"""
|
|
40
|
+
if override is None:
|
|
41
|
+
return default_visit_sequence(incomplete_columns)
|
|
42
|
+
|
|
43
|
+
incomplete_set = set(incomplete_columns)
|
|
44
|
+
seq = tuple(int(j) for j in override)
|
|
45
|
+
|
|
46
|
+
unknown = [j for j in seq if j not in incomplete_set]
|
|
47
|
+
if unknown:
|
|
48
|
+
raise ValidationError(
|
|
49
|
+
f"visit_sequence references columns {unknown} that have no missing "
|
|
50
|
+
f"values. Incomplete columns are {sorted(incomplete_set)}."
|
|
51
|
+
)
|
|
52
|
+
missing_from_seq = incomplete_set - set(seq)
|
|
53
|
+
if missing_from_seq:
|
|
54
|
+
raise ValidationError(
|
|
55
|
+
f"visit_sequence omits incomplete columns {sorted(missing_from_seq)}; "
|
|
56
|
+
f"their missing values would never be imputed."
|
|
57
|
+
)
|
|
58
|
+
return seq
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Compute backends for MICE (CPU in Stage 1; GPU planned for Stage 2)."""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CPU backend for MICE.
|
|
3
|
+
|
|
4
|
+
Owns the single backend entrypoint ``run`` that the solver calls. It runs the
|
|
5
|
+
``m`` imputation chains — each with its own pre-spawned, independent RNG stream
|
|
6
|
+
— and assembles the completed datasets and convergence traces into a Result.
|
|
7
|
+
|
|
8
|
+
This is the seam Stage 2 mirrors: a GPU backend implements the same ``run``
|
|
9
|
+
signature and batches the chain loop, while the solver, design, methods, and
|
|
10
|
+
pooling stay untouched.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
|
|
17
|
+
from pystatistics.core.compute.timing import Timer
|
|
18
|
+
from pystatistics.core.result import Result
|
|
19
|
+
from pystatistics.mice._chain import run_chain
|
|
20
|
+
from pystatistics.mice.design import MICEDesign
|
|
21
|
+
from pystatistics.mice.solution import MICEParams
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CPUMiceBackend:
|
|
25
|
+
"""Runs MICE chains on the CPU (reference path)."""
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def name(self) -> str:
|
|
29
|
+
return "cpu"
|
|
30
|
+
|
|
31
|
+
def run(
|
|
32
|
+
self,
|
|
33
|
+
design: MICEDesign,
|
|
34
|
+
*,
|
|
35
|
+
m: int,
|
|
36
|
+
maxit: int,
|
|
37
|
+
visit_sequence: tuple[int, ...],
|
|
38
|
+
streams: list[np.random.Generator],
|
|
39
|
+
) -> Result[MICEParams]:
|
|
40
|
+
"""Run ``m`` chains and package the imputations.
|
|
41
|
+
|
|
42
|
+
Parameters
|
|
43
|
+
----------
|
|
44
|
+
design : MICEDesign
|
|
45
|
+
m : int
|
|
46
|
+
Number of imputations (chains).
|
|
47
|
+
maxit : int
|
|
48
|
+
Iterations per chain.
|
|
49
|
+
visit_sequence : tuple of int
|
|
50
|
+
Column visit order within each iteration.
|
|
51
|
+
streams : list of numpy.random.Generator
|
|
52
|
+
One independent RNG per chain; ``len(streams) == m`` (the solver
|
|
53
|
+
guarantees this).
|
|
54
|
+
"""
|
|
55
|
+
timer = Timer()
|
|
56
|
+
timer.start()
|
|
57
|
+
|
|
58
|
+
completed = np.empty((m, design.n, design.p), dtype=np.float64)
|
|
59
|
+
chain_means = np.empty((m, maxit, len(design.incomplete_columns)))
|
|
60
|
+
chain_vars = np.empty((m, maxit, len(design.incomplete_columns)))
|
|
61
|
+
|
|
62
|
+
with timer.section("chains"):
|
|
63
|
+
for i in range(m):
|
|
64
|
+
result = run_chain(design, streams[i], maxit, visit_sequence)
|
|
65
|
+
completed[i] = result.completed
|
|
66
|
+
chain_means[i] = result.chain_mean
|
|
67
|
+
chain_vars[i] = result.chain_var
|
|
68
|
+
|
|
69
|
+
timer.stop()
|
|
70
|
+
|
|
71
|
+
params = MICEParams(
|
|
72
|
+
completed=completed,
|
|
73
|
+
chain_mean=chain_means,
|
|
74
|
+
chain_var=chain_vars,
|
|
75
|
+
incomplete_columns=design.incomplete_columns,
|
|
76
|
+
m=m,
|
|
77
|
+
maxit=maxit,
|
|
78
|
+
visit_sequence=visit_sequence,
|
|
79
|
+
)
|
|
80
|
+
return Result(
|
|
81
|
+
params=params,
|
|
82
|
+
info={
|
|
83
|
+
"method": "chained_equations",
|
|
84
|
+
"m": m,
|
|
85
|
+
"maxit": maxit,
|
|
86
|
+
"device": "cpu",
|
|
87
|
+
"visit_sequence": list(visit_sequence),
|
|
88
|
+
},
|
|
89
|
+
timing=timer.result(),
|
|
90
|
+
backend_name="cpu",
|
|
91
|
+
warnings=(),
|
|
92
|
+
)
|