pystatistics 3.2.0__tar.gz → 3.4.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.4.0/.release/UNRELEASED.md +29 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/CHANGELOG.md +42 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/PKG-INFO +47 -1
- {pystatistics-3.2.0 → pystatistics-3.4.0}/README.md +46 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pyproject.toml +1 -1
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/__init__.py +3 -1
- pystatistics-3.4.0/pystatistics/mice/__init__.py +29 -0
- pystatistics-3.4.0/pystatistics/mice/_chain.py +113 -0
- pystatistics-3.4.0/pystatistics/mice/_rng.py +88 -0
- pystatistics-3.4.0/pystatistics/mice/_visit.py +58 -0
- pystatistics-3.4.0/pystatistics/mice/backends/__init__.py +1 -0
- pystatistics-3.4.0/pystatistics/mice/backends/_gpu_linreg.py +138 -0
- pystatistics-3.4.0/pystatistics/mice/backends/_gpu_methods.py +81 -0
- pystatistics-3.4.0/pystatistics/mice/backends/cpu.py +95 -0
- pystatistics-3.4.0/pystatistics/mice/backends/gpu.py +170 -0
- pystatistics-3.4.0/pystatistics/mice/datasets.py +116 -0
- pystatistics-3.4.0/pystatistics/mice/design.py +373 -0
- pystatistics-3.4.0/pystatistics/mice/methods/__init__.py +27 -0
- pystatistics-3.4.0/pystatistics/mice/methods/_linreg.py +133 -0
- pystatistics-3.4.0/pystatistics/mice/methods/base.py +57 -0
- pystatistics-3.4.0/pystatistics/mice/methods/norm.py +42 -0
- pystatistics-3.4.0/pystatistics/mice/methods/pmm.py +86 -0
- pystatistics-3.4.0/pystatistics/mice/methods/registry.py +59 -0
- pystatistics-3.4.0/pystatistics/mice/pooling.py +181 -0
- pystatistics-3.4.0/pystatistics/mice/solution.py +156 -0
- pystatistics-3.4.0/pystatistics/mice/solvers.py +170 -0
- pystatistics-3.4.0/tests/mice/references/generate_mice_fixtures.R +104 -0
- pystatistics-3.4.0/tests/mice/references/mice_reference.json +78 -0
- pystatistics-3.4.0/tests/mice/references/mice_validation_complete.csv +201 -0
- pystatistics-3.4.0/tests/mice/references/mice_validation_data.csv +201 -0
- pystatistics-3.4.0/tests/mice/test_datasets.py +68 -0
- pystatistics-3.4.0/tests/mice/test_design.py +128 -0
- pystatistics-3.4.0/tests/mice/test_gpu.py +146 -0
- pystatistics-3.4.0/tests/mice/test_methods.py +141 -0
- pystatistics-3.4.0/tests/mice/test_mice.py +162 -0
- pystatistics-3.4.0/tests/mice/test_pooling.py +142 -0
- pystatistics-3.4.0/tests/mice/test_r_validation.py +152 -0
- pystatistics-3.4.0/tests/mice/test_rng.py +76 -0
- pystatistics-3.4.0/tests/mice/test_visit.py +34 -0
- pystatistics-3.4.0/tests/timeseries/__init__.py +0 -0
- pystatistics-3.2.0/.release/UNRELEASED.md +0 -42
- {pystatistics-3.2.0 → pystatistics-3.4.0}/.github/workflows/publish.yml +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/.github/workflows/trigger-docs-rebuild.yml +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/.gitignore +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/.release/CHECKLIST.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/.release/release.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/CLAUDE.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/LICENSE +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/benchmarks/mvnmle_bench.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/DESIGN.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/Forge.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/GPU_BACKEND_NOTES.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/Makefile +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/PYSTATSBIO_CONTEXT.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/ROADMAP.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/_static/custom.css +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/anova.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/conf.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/core.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/descriptive.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/gam.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/hypothesis.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/index.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/mixed.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/montecarlo.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/multinomial.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/multivariate.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/mvnmle.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/ordinal.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/regression.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/survival.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/docs/timeseries.rst +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/GPU_BACKEND_CONVENTION.md +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_contrasts.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_levene.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_posthoc.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_repeated.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/_ss.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/anova/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/capabilities.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/device.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/batched.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/cholesky.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/determinant.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/qr.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/solve.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/linalg/svd.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/optimization/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/optimization/convergence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/precision.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/timing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/tolerances.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/compute/torch_interop.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/datasource.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/encoding.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/exceptions.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/protocols.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/result.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/core/validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/_missing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/_quantile_types.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/descriptive/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_basis.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_gam.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_gcv.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/_smooth.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/backends/_gpu_family.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/backends/gpu_pirls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/gam/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/_design_factories.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/_p_adjust.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_chisq_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_fisher_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_ks_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_prop_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_t_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_var_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/_wilcox_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/hypothesis/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_deviance.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_pirls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_pls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_random_effects.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/_satterthwaite.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mixed/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/_ci.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/_influence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/montecarlo/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/backends/gpu_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multinomial/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/_factor.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/_pca.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/_rotation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/multivariate/backends/gpu_pca.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_monotone.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/base.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/gpu_fp32.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/gpu_fp64.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_objectives/parameterizations.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/_utils.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/_em_batched.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/_em_batched_np.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/_em_batched_patterns.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/_em_batched_torch.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/_squarem.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/em.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/datasets.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/mcar_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/patterns.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/mvnmle/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/backends/gpu_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/ordinal/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/py.typed +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/_formatting.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/_linear.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/_nb_theta.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/backends/cpu_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/backends/gpu_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/families.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/regression/terms.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/_cox.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/_discrete.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/_km.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/_logrank.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/backends/cpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/backends/gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/solution.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/survival/solvers.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_acf.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_batch.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_factored.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_forecast.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_kalman.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_likelihood.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_arima_order.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_common.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_decomposition.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_differencing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_ets_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_ets_forecast.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_ets_models.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_stationarity.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/_whittle.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/backends/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/backends/whittle_batch_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/pystatistics/timeseries/backends/whittle_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_contrasts.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_design.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_factorial.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_levene.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_oneway.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_posthoc.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/anova/test_repeated_measures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/benchmark_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/core/test_datasource.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/core/test_exceptions.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/core/test_result.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/core/test_torch_interop.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/core/test_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_cor.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_cov.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_describe.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_missing.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_moments.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_quantile.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/descriptive/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_ancova_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_ancova_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_bonferroni_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_bonferroni_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_eta_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_eta_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_levene_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_levene_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_oneway_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_oneway_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_oneway_unbalanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_oneway_unbalanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_rm_mixed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_rm_mixed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_rm_within_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_rm_within_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_tukey_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_tukey_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_twoway_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_twoway_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_twoway_unbalanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/anova_twoway_unbalanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/basic_100x3.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/basic_100x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/basic_100x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/collinear_almost.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/collinear_almost_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/collinear_almost_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_basic_100x5.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_basic_100x5_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_basic_100x5_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_constant_column.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_constant_column_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_constant_column_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_extreme_values.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_extreme_values_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_extreme_values_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_large_1000x10.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_large_1000x10_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_large_1000x10_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_columnwise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_columnwise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_columnwise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_scattered.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_scattered_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_nan_scattered_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_negative_correlation.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_negative_correlation_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_negative_correlation_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_perfect_correlation.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_perfect_correlation_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_perfect_correlation_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_single_column.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_single_column_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_single_column_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_ties.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/desc_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/different_scales.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/different_scales_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/different_scales_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_anova_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_descriptive_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_glm_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_hypothesis_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_mixed_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_montecarlo_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/generate_survival_fixtures.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_balanced.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_large.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_large_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_large_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_separated.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_separated_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_binomial_separated_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_large.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_large_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_gaussian_large_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_basic.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_large_counts.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_large_counts_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_large_counts_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_zeros.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_zeros_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/glm_poisson_zeros_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/high_noise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/high_noise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/high_noise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_2x2_yates_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_2x2_yates_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_3x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_3x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_gof_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_gof_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_gof_unequal_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_chisq_gof_unequal_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_2x2_less_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_2x2_less_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_2x2_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_2x2_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_3x3_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_fisher_3x3_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_ks_onesample_norm_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_ks_onesample_norm_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_ks_twosample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_ks_twosample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_prop_onesample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_prop_onesample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_prop_twosample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_prop_twosample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_onesample_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_onesample_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_paired_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_paired_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_pooled_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_pooled_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_welch_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_t_welch_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_var_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_var_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_wilcox_ranksum_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_wilcox_ranksum_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_wilcox_signed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/htest_wilcox_signed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/ill_conditioned.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/ill_conditioned_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/ill_conditioned_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/large_coeffs.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/large_coeffs_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/large_coeffs_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_90_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_90_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_normal_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_normal_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_skewed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_ci_skewed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_mean_balanced_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_mean_balanced_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_mean_ordinary_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_mean_ordinary_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_median_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_median_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_variance_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_boot_variance_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_greater_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_greater_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_not_significant_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_not_significant_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_significant_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mc_perm_significant_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/glmm_binomial.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/glmm_poisson.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/lmm_crossed.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/lmm_intercept.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/lmm_ml.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/lmm_no_effect.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/lmm_slope.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/mixed_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/mixed/mixed_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/near_square.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/near_square_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/near_square_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/no_intercept.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/no_intercept_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/no_intercept_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_anova_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_descriptive_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_glm_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_hypothesis_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_mixed_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_montecarlo_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_survival_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_r_validation.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/run_validation.sh +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/small_noise.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/small_noise_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/small_noise_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_breslow_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_breslow_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_single_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_single_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_two_cov_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_cox_two_cov_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_basic_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_basic_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_heavy_cens_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_heavy_cens_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_loglog_ci_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_loglog_ci_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_no_cens_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_no_cens_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_plain_ci_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_plain_ci_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_ties_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_km_ties_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_peto_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_peto_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_three_group_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_three_group_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_two_group_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/surv_lr_two_group_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/tall_skinny.csv +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/tall_skinny_meta.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/tall_skinny_r_results.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/fixtures/validate_against_r.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/gam/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/gam/test_gam.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_chisq_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_design_split.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_fisher_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_ks_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_p_adjust.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_prop_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_t_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_var_test.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/hypothesis/test_wilcox_test.py +0 -0
- {pystatistics-3.2.0/tests/mixed → pystatistics-3.4.0/tests/mice}/__init__.py +0 -0
- {pystatistics-3.2.0/tests/montecarlo → pystatistics-3.4.0/tests/mixed}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_glmm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_lmm_crossed.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_lmm_intercept.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_lmm_nested.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_lmm_slope.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_pls.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_random_effects.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mixed/test_satterthwaite.py +0 -0
- {pystatistics-3.2.0/tests/multinomial → pystatistics-3.4.0/tests/montecarlo}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_batched_solver.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_boot_ci.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_bootstrap.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_influence.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_permutation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/montecarlo/test_r_validation.py +0 -0
- {pystatistics-3.2.0/tests/multivariate → pystatistics-3.4.0/tests/multinomial}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/multinomial/test_multinom.py +0 -0
- {pystatistics-3.2.0/tests/ordinal → pystatistics-3.4.0/tests/multivariate}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/multivariate/test_multivariate.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/apple_em_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/apple_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/generate_em_fixtures.R +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_apple.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_complete.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_extreme.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_missvals.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_simple_mcar.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/little_mcar_summary.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/missvals_em_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/missvals_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/references/small_test_reference.json +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_em.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_mcar.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_mlest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_monotone.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_no_silent_fallback.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/mvnmle/test_squarem.py +0 -0
- {pystatistics-3.2.0/tests/survival → pystatistics-3.4.0/tests/ordinal}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/ordinal/test_ordinal.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/benchmark.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/benchmark.r +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_fit.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_gamma_nb.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_glm.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_glm_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_glm_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_module_split.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_stress_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_terms.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/regression/test_terms_gpu.py +0 -0
- {pystatistics-3.2.0/tests/timeseries → pystatistics-3.4.0/tests/survival}/__init__.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/conftest.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_coxph.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_discrete_time.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_gpu.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_kaplan_meier.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_logrank.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/survival/test_r_validation.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/test_code_quality.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/timeseries/test_acf_stationarity.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/timeseries/test_arima.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/timeseries/test_decomposition.py +0 -0
- {pystatistics-3.2.0 → pystatistics-3.4.0}/tests/timeseries/test_ets.py +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
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
|
+
- GPU backend for `mice` (CUDA). `mice(..., backend='gpu')` runs the `m`
|
|
13
|
+
imputation chains batched on the GPU as the leading tensor dimension: each
|
|
14
|
+
sweep step is a batched Bayesian linear solve (`torch.linalg.solve` + batched
|
|
15
|
+
Cholesky) and, for PMM, a batched nearest-neighbour donor search
|
|
16
|
+
(`(m, n_mis, n_obs)` distances → `topk`). `backend='auto'` selects CUDA when
|
|
17
|
+
available, else CPU (never MPS, matching the other modules). New `use_fp64`
|
|
18
|
+
argument runs the GPU path in double precision on CUDA (default FP32).
|
|
19
|
+
- GPU results match the CPU reference distributionally at the GPU/FP32 tolerance
|
|
20
|
+
tier (PMM donor copies are exact in FP64, exact-to-FP32 otherwise). Validated
|
|
21
|
+
in `tests/mice/test_gpu.py` against the CPU path rather than R directly.
|
|
22
|
+
- Measured PMM speedups vs the CPU backend on an RTX 5070 Ti: ~39× at n=1000
|
|
23
|
+
(p=8, m=20, maxit=8) and ~135× at n=3000 (p=10, m=20, maxit=8); the gain grows
|
|
24
|
+
with n because the donor search dominates and batches well on the GPU.
|
|
25
|
+
- Internal: the MICE backend contract now takes a `seed` (each backend spawns
|
|
26
|
+
its own RNG streams) instead of pre-spawned streams, so the CPU and GPU
|
|
27
|
+
backends share one `run()` signature. No public API change.
|
|
28
|
+
- MPS (Apple Silicon) is not yet validated for MICE; `backend='gpu'` raises a
|
|
29
|
+
clear error on MPS rather than running unverified. CUDA is supported.
|
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.4.0
|
|
4
|
+
|
|
5
|
+
GPU acceleration for MICE.
|
|
6
|
+
|
|
7
|
+
- **`mice(..., backend='gpu')` runs on CUDA GPUs.** The `m` imputation chains
|
|
8
|
+
run together on the GPU, with the per-variable linear solves and the
|
|
9
|
+
predictive-mean-matching donor search batched across chains. `backend='auto'`
|
|
10
|
+
uses a CUDA GPU when one is available and falls back to the CPU otherwise.
|
|
11
|
+
- **Large speedups on bigger problems.** Because the donor search dominates and
|
|
12
|
+
parallelises well, the GPU advantage grows with sample size — for example,
|
|
13
|
+
predictive mean matching was roughly 39× faster at n=1000 and 135× faster at
|
|
14
|
+
n=3000 than the CPU backend on an RTX 5070 Ti (m=20, maxit=8). GPU results
|
|
15
|
+
match the CPU backend at the standard GPU/FP32 tolerance.
|
|
16
|
+
- **`use_fp64=True`** runs the GPU path in double precision on CUDA for closer
|
|
17
|
+
agreement with the CPU reference (default is FP32, the fast path).
|
|
18
|
+
- GPU acceleration requires a CUDA GPU; Apple Silicon (MPS) is not yet supported
|
|
19
|
+
for MICE and is refused with a clear message rather than run unverified.
|
|
20
|
+
|
|
21
|
+
## 3.3.0
|
|
22
|
+
|
|
23
|
+
Multiple imputation by chained equations (MICE) for multivariate missing data.
|
|
24
|
+
|
|
25
|
+
- **New `mice` module.** `pystatistics.mice.mice(data, m=5, maxit=5,
|
|
26
|
+
method='pmm', seed=...)` imputes a numeric data matrix that contains missing
|
|
27
|
+
values (NaN) by iteratively modelling each incomplete column from the others,
|
|
28
|
+
and returns `m` completed datasets. Two methods are available: `'pmm'`
|
|
29
|
+
(predictive mean matching — the default, which imputes by copying observed
|
|
30
|
+
donor values) and `'norm'` (Bayesian linear regression). Defaults follow R's
|
|
31
|
+
`mice` package (`m=5`, `maxit=5`, 5 PMM donors, left-to-right visit order).
|
|
32
|
+
- **Reproducible by construction.** A `seed` is required; given the same seed,
|
|
33
|
+
imputations are identical across runs and machines. Each of the `m` chains
|
|
34
|
+
draws from its own independent random stream.
|
|
35
|
+
- **Rubin's-rules pooling.** `pystatistics.mice.pool(estimates, variances)`
|
|
36
|
+
combines an analysis fitted on each completed dataset into a single inference,
|
|
37
|
+
with Barnard–Rubin degrees of freedom, confidence intervals, and the usual
|
|
38
|
+
diagnostics (within/between/total variance, relative increase in variance,
|
|
39
|
+
fraction of missing information).
|
|
40
|
+
- **Validated against R.** Imputed-value distributions and pooled regression
|
|
41
|
+
output are checked against R's `mice` on a shared dataset.
|
|
42
|
+
- This release covers numeric columns on the CPU. Categorical-column methods
|
|
43
|
+
and GPU acceleration are planned for future releases.
|
|
44
|
+
|
|
3
45
|
## 3.2.0
|
|
4
46
|
|
|
5
47
|
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.4.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 | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice; CUDA GPU backend |
|
|
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,30 @@ pip install pystatistics[dev]
|
|
|
391
413
|
|
|
392
414
|
## What's New
|
|
393
415
|
|
|
416
|
+
### 3.4.0 — GPU acceleration for MICE
|
|
417
|
+
|
|
418
|
+
- `mice(..., backend='gpu')` runs the imputation chains on a CUDA GPU, batching
|
|
419
|
+
the per-variable solves and the predictive-mean-matching donor search across
|
|
420
|
+
chains. `backend='auto'` uses a CUDA GPU when available, else the CPU.
|
|
421
|
+
- The speedup grows with sample size (the donor search dominates and batches
|
|
422
|
+
well): predictive mean matching ran ~39× faster at n=1000 and ~135× faster at
|
|
423
|
+
n=3000 than the CPU backend on an RTX 5070 Ti. GPU results match the CPU
|
|
424
|
+
backend at the GPU/FP32 tolerance; pass `use_fp64=True` for double precision.
|
|
425
|
+
- Requires a CUDA GPU; Apple Silicon (MPS) is not yet supported for MICE.
|
|
426
|
+
|
|
427
|
+
### 3.3.0 — Multiple imputation (MICE)
|
|
428
|
+
|
|
429
|
+
- New `mice` module: multiple imputation by chained equations for numeric data
|
|
430
|
+
with missing values. `mice(data, m=5, method='pmm', seed=...)` returns `m`
|
|
431
|
+
completed datasets, using predictive mean matching (the R default) or
|
|
432
|
+
Bayesian linear regression (`method='norm'`). Defaults follow R's `mice`.
|
|
433
|
+
- Imputation is fully reproducible — `seed` is required, and each chain uses an
|
|
434
|
+
independent random stream.
|
|
435
|
+
- `pool(estimates, variances)` combines per-dataset analyses with Rubin's rules
|
|
436
|
+
(Barnard–Rubin degrees of freedom, confidence intervals, fraction of missing
|
|
437
|
+
information).
|
|
438
|
+
- Numeric columns on the CPU in this release; validated against R's `mice`.
|
|
439
|
+
|
|
394
440
|
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
395
441
|
|
|
396
442
|
- `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 | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice; CUDA GPU backend |
|
|
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,30 @@ pip install pystatistics[dev]
|
|
|
344
366
|
|
|
345
367
|
## What's New
|
|
346
368
|
|
|
369
|
+
### 3.4.0 — GPU acceleration for MICE
|
|
370
|
+
|
|
371
|
+
- `mice(..., backend='gpu')` runs the imputation chains on a CUDA GPU, batching
|
|
372
|
+
the per-variable solves and the predictive-mean-matching donor search across
|
|
373
|
+
chains. `backend='auto'` uses a CUDA GPU when available, else the CPU.
|
|
374
|
+
- The speedup grows with sample size (the donor search dominates and batches
|
|
375
|
+
well): predictive mean matching ran ~39× faster at n=1000 and ~135× faster at
|
|
376
|
+
n=3000 than the CPU backend on an RTX 5070 Ti. GPU results match the CPU
|
|
377
|
+
backend at the GPU/FP32 tolerance; pass `use_fp64=True` for double precision.
|
|
378
|
+
- Requires a CUDA GPU; Apple Silicon (MPS) is not yet supported for MICE.
|
|
379
|
+
|
|
380
|
+
### 3.3.0 — Multiple imputation (MICE)
|
|
381
|
+
|
|
382
|
+
- New `mice` module: multiple imputation by chained equations for numeric data
|
|
383
|
+
with missing values. `mice(data, m=5, method='pmm', seed=...)` returns `m`
|
|
384
|
+
completed datasets, using predictive mean matching (the R default) or
|
|
385
|
+
Bayesian linear regression (`method='norm'`). Defaults follow R's `mice`.
|
|
386
|
+
- Imputation is fully reproducible — `seed` is required, and each chain uses an
|
|
387
|
+
independent random stream.
|
|
388
|
+
- `pool(estimates, variances)` combines per-dataset analyses with Rubin's rules
|
|
389
|
+
(Barnard–Rubin degrees of freedom, confidence intervals, fraction of missing
|
|
390
|
+
information).
|
|
391
|
+
- Numeric columns on the CPU in this release; validated against R's `mice`.
|
|
392
|
+
|
|
347
393
|
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
348
394
|
|
|
349
395
|
- `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.4.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)."""
|