pystatistics 3.1.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.1.0 → pystatistics-3.3.0}/CHANGELOG.md +59 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/PKG-INFO +55 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/README.md +54 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pyproject.toml +1 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/__init__.py +3 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/device.py +13 -2
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/batched.py +10 -3
- pystatistics-3.3.0/pystatistics/core/compute/torch_interop.py +48 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/datasource.py +10 -2
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_gam.py +5 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/backends/gpu_pirls.py +13 -12
- 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.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/_solver.py +5 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/backends/gpu_likelihood.py +5 -3
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/_pca.py +5 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/backends/gpu_pca.py +25 -12
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/solvers.py +11 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/_solver.py +5 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/backends/gpu_likelihood.py +4 -2
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_batch.py +5 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_whittle.py +18 -2
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/whittle_batch_gpu.py +6 -4
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/whittle_gpu.py +3 -1
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/core/test_datasource.py +37 -14
- pystatistics-3.3.0/tests/core/test_torch_interop.py +58 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/gam/test_gam.py +5 -3
- 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.1.0 → pystatistics-3.3.0}/tests/multinomial/test_multinom.py +12 -5
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/multivariate/test_multivariate.py +26 -4
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_gpu.py +7 -3
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/ordinal/test_ordinal.py +12 -5
- pystatistics-3.3.0/tests/timeseries/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/timeseries/test_arima.py +33 -9
- pystatistics-3.1.0/.release/UNRELEASED.md +0 -42
- {pystatistics-3.1.0 → pystatistics-3.3.0}/.github/workflows/publish.yml +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/.github/workflows/trigger-docs-rebuild.yml +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/.gitignore +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/.release/CHECKLIST.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/.release/release.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/CLAUDE.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/LICENSE +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/benchmarks/mvnmle_bench.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/DESIGN.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/Forge.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/GPU_BACKEND_NOTES.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/Makefile +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/PYSTATSBIO_CONTEXT.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/ROADMAP.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/_static/custom.css +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/anova.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/conf.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/core.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/descriptive.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/gam.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/hypothesis.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/index.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/mixed.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/montecarlo.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/multinomial.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/multivariate.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/mvnmle.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/ordinal.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/regression.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/survival.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/docs/timeseries.rst +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/GPU_BACKEND_CONVENTION.md +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_contrasts.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_levene.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_posthoc.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_repeated.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/_ss.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/anova/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/capabilities.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/cholesky.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/determinant.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/qr.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/solve.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/linalg/svd.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/optimization/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/optimization/convergence.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/precision.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/timing.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/compute/tolerances.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/encoding.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/exceptions.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/protocols.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/result.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/core/validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/_missing.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/_quantile_types.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/descriptive/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_basis.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_fit.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_gcv.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/_smooth.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/backends/_gpu_family.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/gam/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_design_factories.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/_p_adjust.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_chisq_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_fisher_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_ks_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_prop_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_t_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_var_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/_wilcox_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/hypothesis/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_deviance.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_pirls.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_pls.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_random_effects.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/_satterthwaite.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mixed/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_ci.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/_influence.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/montecarlo/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/_likelihood.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multinomial/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/_factor.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/_rotation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/multivariate/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_monotone.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/base.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/gpu_fp32.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/gpu_fp64.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_objectives/parameterizations.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/_utils.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_np.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_patterns.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_em_batched_torch.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/_squarem.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/em.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/datasets.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/mcar_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/patterns.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/mvnmle/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/_likelihood.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/ordinal/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/py.typed +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/_formatting.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/_glm.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/_linear.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/_nb_theta.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/backends/cpu_glm.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/backends/gpu_glm.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/families.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/regression/terms.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/_cox.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/_discrete.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/_km.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/_logrank.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/backends/cpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/backends/gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/solution.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/survival/solvers.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_acf.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_factored.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_fit.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_forecast.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_kalman.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_likelihood.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_arima_order.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_common.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_decomposition.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_differencing.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_fit.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_forecast.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_ets_models.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/_stationarity.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/pystatistics/timeseries/backends/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_contrasts.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_design.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_factorial.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_levene.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_oneway.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_posthoc.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/anova/test_repeated_measures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/benchmark_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/core/test_exceptions.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/core/test_result.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/core/test_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_cor.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_cov.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_describe.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_missing.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_moments.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_quantile.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/descriptive/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_ancova_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_ancova_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_bonferroni_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_bonferroni_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_eta_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_eta_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_levene_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_levene_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_balanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_balanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_unbalanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_oneway_unbalanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_mixed_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_mixed_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_within_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_rm_within_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_tukey_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_tukey_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_balanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_balanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_unbalanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/anova_twoway_unbalanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/basic_100x3_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/collinear_almost_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_basic_100x5_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_constant_column_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_extreme_values_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_large_1000x10_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_columnwise_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_nan_scattered_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_negative_correlation_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_perfect_correlation_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_single_column_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/desc_ties_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/different_scales.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/different_scales_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/different_scales_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_anova_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_descriptive_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_glm_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_hypothesis_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_mixed_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_montecarlo_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/generate_survival_fixtures.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_balanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_basic_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_large_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_binomial_separated_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_basic_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_gaussian_large_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_basic_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_large_counts_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/glm_poisson_zeros_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/high_noise.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/high_noise_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/high_noise_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_2x2_yates_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_2x2_yates_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_3x3_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_3x3_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_unequal_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_chisq_gof_unequal_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_less_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_less_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_2x2_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_3x3_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_fisher_3x3_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_onesample_norm_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_onesample_norm_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_twosample_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_ks_twosample_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_onesample_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_onesample_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_twosample_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_prop_twosample_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_onesample_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_onesample_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_paired_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_paired_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_pooled_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_pooled_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_welch_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_t_welch_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_var_basic_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_var_basic_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_ranksum_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_ranksum_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_signed_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/htest_wilcox_signed_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/ill_conditioned_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/large_coeffs_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_90_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_90_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_normal_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_normal_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_skewed_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_ci_skewed_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_balanced_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_balanced_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_ordinary_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_mean_ordinary_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_median_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_median_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_variance_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_boot_variance_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_greater_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_greater_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_not_significant_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_not_significant_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_significant_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mc_perm_significant_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/glmm_binomial.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/glmm_poisson.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_crossed.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_intercept.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_ml.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_no_effect.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/lmm_slope.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/mixed_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/mixed/mixed_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/near_square.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/near_square_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/near_square_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/no_intercept_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_anova_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_descriptive_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_glm_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_hypothesis_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_mixed_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_montecarlo_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_survival_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_r_validation.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/run_validation.sh +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/small_noise.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/small_noise_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/small_noise_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_breslow_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_breslow_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_single_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_single_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_ties_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_ties_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_two_cov_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_cox_two_cov_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_basic_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_basic_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_heavy_cens_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_heavy_cens_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_loglog_ci_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_loglog_ci_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_no_cens_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_no_cens_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_plain_ci_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_plain_ci_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_ties_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_km_ties_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_peto_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_peto_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_three_group_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_three_group_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_two_group_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/surv_lr_two_group_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny.csv +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny_meta.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/tall_skinny_r_results.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/fixtures/validate_against_r.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/gam/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_chisq_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_design_split.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_fisher_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_ks_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_p_adjust.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_prop_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_t_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_var_test.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/hypothesis/test_wilcox_test.py +0 -0
- {pystatistics-3.1.0/tests/mixed → pystatistics-3.3.0/tests/mice}/__init__.py +0 -0
- {pystatistics-3.1.0/tests/montecarlo → pystatistics-3.3.0/tests/mixed}/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_glmm.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_crossed.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_intercept.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_nested.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_lmm_slope.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_pls.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_random_effects.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mixed/test_satterthwaite.py +0 -0
- {pystatistics-3.1.0/tests/multinomial → pystatistics-3.3.0/tests/montecarlo}/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_batched_solver.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_boot_ci.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_bootstrap.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_influence.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_permutation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/montecarlo/test_r_validation.py +0 -0
- {pystatistics-3.1.0/tests/multivariate → pystatistics-3.3.0/tests/multinomial}/__init__.py +0 -0
- {pystatistics-3.1.0/tests/ordinal → pystatistics-3.3.0/tests/multivariate}/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/apple_em_reference.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/apple_reference.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/generate_em_fixtures.R +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_apple.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_complete.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_extreme.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_missvals.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_simple_mcar.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/little_mcar_summary.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/missvals_em_reference.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/missvals_reference.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/references/small_test_reference.json +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_em.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_mcar.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_mlest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_monotone.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_no_silent_fallback.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/mvnmle/test_squarem.py +0 -0
- {pystatistics-3.1.0/tests/survival → pystatistics-3.3.0/tests/ordinal}/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/benchmark.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/benchmark.r +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_fit.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_gamma_nb.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_glm.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_glm_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_glm_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_module_split.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_stress_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_terms.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/regression/test_terms_gpu.py +0 -0
- {pystatistics-3.1.0/tests/timeseries → pystatistics-3.3.0/tests/survival}/__init__.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/conftest.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_coxph.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_discrete_time.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_gpu.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_kaplan_meier.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_logrank.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/survival/test_r_validation.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/test_code_quality.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/timeseries/test_acf_stationarity.py +0 -0
- {pystatistics-3.1.0 → pystatistics-3.3.0}/tests/timeseries/test_decomposition.py +0 -0
- {pystatistics-3.1.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,64 @@
|
|
|
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
|
+
|
|
27
|
+
## 3.2.0
|
|
28
|
+
|
|
29
|
+
Apple Silicon (MPS) GPU support for the FP32 backends, with honest,
|
|
30
|
+
fail-fast boundaries where Metal can't deliver a real GPU path.
|
|
31
|
+
|
|
32
|
+
- **GPU fitting now runs on Apple Silicon (MPS) for `multinom`, `polr`,
|
|
33
|
+
`gam`, and `arima` / `arima_batch` (Whittle).** Pass `backend='gpu'` on
|
|
34
|
+
a Mac with an Apple GPU to run these fits in FP32 on Metal. Every
|
|
35
|
+
operation on these paths is a native Metal kernel — there is no hidden
|
|
36
|
+
fallback to the CPU. Results match the CPU backend at the documented
|
|
37
|
+
GPU/FP32 tolerance tier. (MPS has no double precision, so `use_fp64=True`
|
|
38
|
+
is rejected on MPS; CUDA FP64 is unchanged.)
|
|
39
|
+
- **`DataSource.to('mps')`** now transfers arrays to the Apple GPU,
|
|
40
|
+
downcasting float64 to float32 (MPS has no float64). This lets you pay
|
|
41
|
+
the host→device copy once and reuse a device-resident `DataSource`
|
|
42
|
+
across multiple GPU fits, as with CUDA.
|
|
43
|
+
- **`backend='auto'` never selects MPS.** On Apple Silicon, `'auto'`
|
|
44
|
+
uses the CPU (double precision, the R-validated path); the Apple GPU is
|
|
45
|
+
opt-in only via an explicit `backend='gpu'`. CUDA continues to be
|
|
46
|
+
auto-selected. This matches how the regression and MVN MLE backends
|
|
47
|
+
already behaved.
|
|
48
|
+
- **PCA and MVN MLE GPU remain CUDA-only.** `pca(backend='gpu')` and
|
|
49
|
+
`mlest(algorithm='em', backend='gpu')` now raise a clear error on Apple
|
|
50
|
+
Silicon instead of running silently on the CPU under a `gpu` label: PCA
|
|
51
|
+
needs an SVD / eigendecomposition that Metal does not implement, and the
|
|
52
|
+
EM algorithm's iterative, small-step pattern is far slower on Metal than
|
|
53
|
+
on the CPU. Use `backend='cpu'` (or `backend='auto'`, which selects the
|
|
54
|
+
CPU on MPS). CUDA is supported for both. MVN MLE *direct* (BFGS) GPU
|
|
55
|
+
fitting is unaffected and works on MPS.
|
|
56
|
+
- **Whittle ARIMA GPU is more robust in FP32.** When the optimizer's line
|
|
57
|
+
search stalls at the FP32 noise floor on an already-converged fit, the
|
|
58
|
+
result is now accepted (it matches the CPU fit at the FP32 tier) instead
|
|
59
|
+
of raising a spurious convergence error. Non-stationary fits are still
|
|
60
|
+
rejected.
|
|
61
|
+
|
|
3
62
|
## 3.1.0
|
|
4
63
|
|
|
5
64
|
Categorical predictors and interaction terms in regression.
|
|
@@ -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,38 @@ 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
|
+
|
|
429
|
+
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
430
|
+
|
|
431
|
+
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
432
|
+
on Apple Silicon GPUs with `backend='gpu'`, in FP32 and entirely on
|
|
433
|
+
native Metal kernels (no hidden CPU fallback). Results match the CPU
|
|
434
|
+
backend at the GPU/FP32 tolerance tier.
|
|
435
|
+
- `DataSource.to('mps')` transfers data to the Apple GPU (float64 →
|
|
436
|
+
float32), so you can pay the host→device copy once and reuse it across
|
|
437
|
+
fits.
|
|
438
|
+
- `backend='auto'` uses the CPU on Apple Silicon; the Apple GPU is opt-in
|
|
439
|
+
via an explicit `backend='gpu'`. CUDA is still auto-selected.
|
|
440
|
+
- `pca` and MVN MLE `em` GPU paths remain CUDA-only and now raise a clear
|
|
441
|
+
error on Apple Silicon rather than silently running on the CPU — PCA's
|
|
442
|
+
SVD/eigendecomposition and the EM scatter/iteration pattern have no
|
|
443
|
+
efficient Metal equivalent. Use `backend='cpu'` or `'auto'` on a Mac.
|
|
444
|
+
(MVN MLE *direct* GPU fitting works on MPS.)
|
|
445
|
+
- Whittle ARIMA GPU fits no longer raise a spurious convergence error when
|
|
446
|
+
the FP32 line search stalls at an already-converged optimum.
|
|
447
|
+
|
|
394
448
|
### 3.1.0 — Categorical predictors & interaction terms
|
|
395
449
|
|
|
396
450
|
- Regression now supports categorical predictors and interactions via a
|
|
@@ -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,38 @@ 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
|
+
|
|
382
|
+
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
383
|
+
|
|
384
|
+
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
385
|
+
on Apple Silicon GPUs with `backend='gpu'`, in FP32 and entirely on
|
|
386
|
+
native Metal kernels (no hidden CPU fallback). Results match the CPU
|
|
387
|
+
backend at the GPU/FP32 tolerance tier.
|
|
388
|
+
- `DataSource.to('mps')` transfers data to the Apple GPU (float64 →
|
|
389
|
+
float32), so you can pay the host→device copy once and reuse it across
|
|
390
|
+
fits.
|
|
391
|
+
- `backend='auto'` uses the CPU on Apple Silicon; the Apple GPU is opt-in
|
|
392
|
+
via an explicit `backend='gpu'`. CUDA is still auto-selected.
|
|
393
|
+
- `pca` and MVN MLE `em` GPU paths remain CUDA-only and now raise a clear
|
|
394
|
+
error on Apple Silicon rather than silently running on the CPU — PCA's
|
|
395
|
+
SVD/eigendecomposition and the EM scatter/iteration pattern have no
|
|
396
|
+
efficient Metal equivalent. Use `backend='cpu'` or `'auto'` on a Mac.
|
|
397
|
+
(MVN MLE *direct* GPU fitting works on MPS.)
|
|
398
|
+
- Whittle ARIMA GPU fits no longer raise a spurious convergence error when
|
|
399
|
+
the FP32 line search stalls at an already-converged optimum.
|
|
400
|
+
|
|
347
401
|
### 3.1.0 — Categorical predictors & interaction terms
|
|
348
402
|
|
|
349
403
|
- Regression now supports categorical predictors and interactions via a
|
|
@@ -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
|
]
|
|
@@ -118,12 +118,23 @@ def select_device(prefer: Literal['cpu', 'gpu', 'auto'] = 'auto') -> DeviceInfo:
|
|
|
118
118
|
- 'cpu': Always use CPU
|
|
119
119
|
- 'gpu': Require GPU (raises if unavailable)
|
|
120
120
|
- 'auto': Use GPU if available, else CPU
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
Returns:
|
|
123
123
|
DeviceInfo for selected device
|
|
124
|
-
|
|
124
|
+
|
|
125
125
|
Raises:
|
|
126
126
|
RuntimeError: If 'gpu' requested but no GPU available
|
|
127
|
+
|
|
128
|
+
Note:
|
|
129
|
+
This is a hardware *detector*: with ``prefer='auto'`` it returns
|
|
130
|
+
the best available GPU, which includes Apple Silicon MPS. It does
|
|
131
|
+
NOT encode the project's dispatch policy. The fitting functions
|
|
132
|
+
deliberately do NOT auto-select MPS (it is FP32-only and not the
|
|
133
|
+
R-validated default); they treat ``'auto'`` as "GPU only if
|
|
134
|
+
``device_type == 'cuda'``, else CPU", and run on MPS only when the
|
|
135
|
+
caller passes ``backend='gpu'`` explicitly. Keep that check in the
|
|
136
|
+
caller, not here, so ``select_device`` stays a pure capability
|
|
137
|
+
query.
|
|
127
138
|
"""
|
|
128
139
|
if prefer == 'cpu':
|
|
129
140
|
return get_cpu_info()
|
|
@@ -145,9 +145,16 @@ def _batched_ols_gpu(X: NDArray, Y: NDArray, device: str) -> NDArray:
|
|
|
145
145
|
L.T, Z, upper=True,
|
|
146
146
|
)
|
|
147
147
|
except torch._C._LinAlgError:
|
|
148
|
-
# Fallback: lstsq
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
# Fallback for rank-deficient X: lstsq. MPS has no lstsq, and
|
|
149
|
+
# the normal-equations Cholesky we just tried is exactly what
|
|
150
|
+
# failed, so route the rank-revealing solve through CPU LAPACK
|
|
151
|
+
# (the matrices are small here and this path is rare).
|
|
152
|
+
if torch_device.type == 'mps':
|
|
153
|
+
result = torch.linalg.lstsq(X_t.cpu(), Y_t.cpu())
|
|
154
|
+
B = result.solution.to(torch_device)
|
|
155
|
+
else:
|
|
156
|
+
result = torch.linalg.lstsq(X_t, Y_t)
|
|
157
|
+
B = result.solution
|
|
151
158
|
|
|
152
159
|
# Transfer back to CPU
|
|
153
160
|
return B.cpu().numpy().astype(np.float64)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Host/device transfer helpers for the PyTorch GPU backends.
|
|
2
|
+
|
|
3
|
+
One job: move tensors off a compute device into host numpy arrays
|
|
4
|
+
correctly across CUDA and Apple Silicon (MPS).
|
|
5
|
+
|
|
6
|
+
The single invariant this module exists to enforce:
|
|
7
|
+
|
|
8
|
+
Cast to float64 only AFTER moving the tensor to the host.
|
|
9
|
+
|
|
10
|
+
MPS has no float64 dtype, so an on-device ``tensor.to(torch.float64)``
|
|
11
|
+
raises ``TypeError: Cannot convert a MPS Tensor to float64``. The
|
|
12
|
+
download must therefore be ``.cpu().to(torch.float64)``, never
|
|
13
|
+
``.to(torch.float64).cpu()``. Centralising it here means no backend
|
|
14
|
+
can reintroduce the device-side cast by accident (Coding Bible: make
|
|
15
|
+
the wrong thing hard to do accidentally).
|
|
16
|
+
|
|
17
|
+
This is also correct and lossless on CUDA: for a float64-on-device
|
|
18
|
+
tensor the host-side cast is a no-op; for a float32 tensor the
|
|
19
|
+
resulting float64 values are identical regardless of cast order.
|
|
20
|
+
|
|
21
|
+
``torch`` is imported lazily inside each function so that importing
|
|
22
|
+
this module never pulls torch into a CPU-only install.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from typing import Any
|
|
28
|
+
|
|
29
|
+
import numpy as np
|
|
30
|
+
from numpy.typing import NDArray
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def to_host_f64(tensor: Any) -> NDArray[np.float64]:
|
|
34
|
+
"""Download a torch tensor to a contiguous float64 numpy array.
|
|
35
|
+
|
|
36
|
+
Detaches from autograd, moves to the host, then casts to float64
|
|
37
|
+
(in that order — see the module docstring for why the order is
|
|
38
|
+
load-bearing on MPS). Safe on CUDA, MPS, and CPU tensors.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
tensor: A ``torch.Tensor`` on any device.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
A float64 ``numpy.ndarray`` with the tensor's values.
|
|
45
|
+
"""
|
|
46
|
+
import torch
|
|
47
|
+
|
|
48
|
+
return tensor.detach().cpu().to(torch.float64).numpy()
|
|
@@ -385,11 +385,19 @@ class DataSource:
|
|
|
385
385
|
else:
|
|
386
386
|
# Coerce numpy→torch on device; move torch to device.
|
|
387
387
|
if isinstance(value, torch.Tensor):
|
|
388
|
-
|
|
388
|
+
tensor = value
|
|
389
389
|
elif isinstance(value, np.ndarray):
|
|
390
|
-
|
|
390
|
+
tensor = torch.as_tensor(value)
|
|
391
391
|
else:
|
|
392
392
|
new_storage[key] = value
|
|
393
|
+
continue
|
|
394
|
+
# MPS has no float64. Downcast double tensors to float32
|
|
395
|
+
# before transfer so the device-resident path works on
|
|
396
|
+
# Apple Silicon; CUDA keeps the source dtype (FP64 is the
|
|
397
|
+
# R-validated path there).
|
|
398
|
+
if target.type == "mps" and tensor.dtype == torch.float64:
|
|
399
|
+
tensor = tensor.to(torch.float32)
|
|
400
|
+
new_storage[key] = tensor.to(target)
|
|
393
401
|
|
|
394
402
|
capabilities = {CAPABILITY_MATERIALIZED, CAPABILITY_REPEATABLE}
|
|
395
403
|
if target_is_gpu:
|
|
@@ -169,7 +169,11 @@ def gam(
|
|
|
169
169
|
if backend != "cpu":
|
|
170
170
|
from pystatistics.core.compute.device import select_device
|
|
171
171
|
dev = select_device("gpu" if backend == "gpu" else "auto")
|
|
172
|
-
|
|
172
|
+
# backend='auto' must not select MPS: it is FP32-only and not the
|
|
173
|
+
# R-validated default. MPS runs only on explicit backend='gpu';
|
|
174
|
+
# 'auto' uses the GPU only for CUDA (matches the regression and
|
|
175
|
+
# mvnmle dispatch policy).
|
|
176
|
+
if dev.is_gpu and (backend == "gpu" or dev.device_type == "cuda"):
|
|
173
177
|
from pystatistics.gam.backends.gpu_pirls import GAMGPUFitter
|
|
174
178
|
try:
|
|
175
179
|
gpu_fitter = GAMGPUFitter(
|
|
@@ -32,6 +32,7 @@ from typing import Any
|
|
|
32
32
|
import numpy as np
|
|
33
33
|
from numpy.typing import NDArray
|
|
34
34
|
|
|
35
|
+
from pystatistics.core.compute.torch_interop import to_host_f64
|
|
35
36
|
from pystatistics.gam.backends._gpu_family import (
|
|
36
37
|
GPUFamilyOps,
|
|
37
38
|
resolve_gpu_family,
|
|
@@ -173,8 +174,8 @@ class GAMGPUFitter:
|
|
|
173
174
|
FP64 precision.
|
|
174
175
|
"""
|
|
175
176
|
torch = self._torch
|
|
176
|
-
A_np = A
|
|
177
|
-
b_np = b
|
|
177
|
+
A_np = to_host_f64(A)
|
|
178
|
+
b_np = to_host_f64(b)
|
|
178
179
|
try:
|
|
179
180
|
L = np.linalg.cholesky(A_np)
|
|
180
181
|
beta_np = np.linalg.solve(L.T, np.linalg.solve(L, b_np))
|
|
@@ -205,8 +206,8 @@ class GAMGPUFitter:
|
|
|
205
206
|
``X'WX``) stays on device; only the p×p solve goes via host.
|
|
206
207
|
"""
|
|
207
208
|
torch = self._torch
|
|
208
|
-
A_np = A
|
|
209
|
-
XtWX_np = XtWX
|
|
209
|
+
A_np = to_host_f64(A)
|
|
210
|
+
XtWX_np = to_host_f64(XtWX)
|
|
210
211
|
try:
|
|
211
212
|
F_np = np.linalg.solve(A_np, XtWX_np)
|
|
212
213
|
except np.linalg.LinAlgError:
|
|
@@ -330,10 +331,10 @@ class GAMGPUFitter:
|
|
|
330
331
|
mu = self._fam.linkinv(eta)
|
|
331
332
|
|
|
332
333
|
return (
|
|
333
|
-
beta
|
|
334
|
-
mu
|
|
335
|
-
eta
|
|
336
|
-
w
|
|
334
|
+
to_host_f64(beta),
|
|
335
|
+
to_host_f64(mu),
|
|
336
|
+
to_host_f64(eta),
|
|
337
|
+
to_host_f64(w),
|
|
337
338
|
float(dev_t.detach().cpu().item()),
|
|
338
339
|
n_iter,
|
|
339
340
|
converged,
|
|
@@ -426,10 +427,10 @@ class GAMGPUFitter:
|
|
|
426
427
|
return (
|
|
427
428
|
np.asarray(edf_list, dtype=np.float64),
|
|
428
429
|
total_edf,
|
|
429
|
-
beta
|
|
430
|
-
mu
|
|
431
|
-
eta
|
|
432
|
-
w
|
|
430
|
+
to_host_f64(beta),
|
|
431
|
+
to_host_f64(mu),
|
|
432
|
+
to_host_f64(eta),
|
|
433
|
+
to_host_f64(w),
|
|
433
434
|
float(dev_t.detach().cpu().item()),
|
|
434
435
|
n_iter,
|
|
435
436
|
converged,
|
|
@@ -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]
|