pystatistics 3.0.1__tar.gz → 3.2.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.2.0/.release/UNRELEASED.md +42 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/CHANGELOG.md +88 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/PKG-INFO +55 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/README.md +54 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/ROADMAP.md +19 -0
- pystatistics-3.2.0/docs/gam.rst +9 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/index.rst +5 -0
- pystatistics-3.2.0/docs/multinomial.rst +9 -0
- pystatistics-3.2.0/docs/multivariate.rst +9 -0
- pystatistics-3.2.0/docs/ordinal.rst +9 -0
- pystatistics-3.2.0/docs/timeseries.rst +9 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pyproject.toml +1 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/__init__.py +1 -1
- pystatistics-3.2.0/pystatistics/anova/_contrasts.py +28 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/device.py +13 -2
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/batched.py +10 -3
- pystatistics-3.2.0/pystatistics/core/compute/torch_interop.py +48 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/datasource.py +26 -5
- pystatistics-3.0.1/pystatistics/anova/_contrasts.py → pystatistics-3.2.0/pystatistics/core/encoding.py +53 -27
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_gam.py +5 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/backends/gpu_pirls.py +13 -12
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/_solver.py +5 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/backends/gpu_likelihood.py +5 -3
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/_pca.py +5 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/backends/gpu_pca.py +25 -12
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/solvers.py +11 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/_solver.py +5 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/backends/gpu_likelihood.py +4 -2
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/__init__.py +2 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/design.py +69 -9
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/solvers.py +6 -2
- pystatistics-3.2.0/pystatistics/regression/terms.py +211 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/solvers.py +16 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_batch.py +5 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_ets_fit.py +25 -8
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_whittle.py +18 -2
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/backends/whittle_batch_gpu.py +6 -4
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/backends/whittle_gpu.py +3 -1
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/core/test_datasource.py +34 -11
- pystatistics-3.2.0/tests/core/test_torch_interop.py +58 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/gam/test_gam.py +3 -2
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/multinomial/test_multinom.py +9 -2
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/multivariate/test_multivariate.py +28 -7
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_gpu.py +12 -6
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_monotone.py +37 -21
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/ordinal/test_ordinal.py +10 -4
- pystatistics-3.2.0/tests/regression/test_terms.py +181 -0
- pystatistics-3.2.0/tests/regression/test_terms_gpu.py +101 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/timeseries/test_arima.py +30 -8
- pystatistics-3.0.1/.release/UNRELEASED.md +0 -13
- {pystatistics-3.0.1 → pystatistics-3.2.0}/.github/workflows/publish.yml +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/.github/workflows/trigger-docs-rebuild.yml +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/.gitignore +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/.release/CHECKLIST.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/.release/release.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/CLAUDE.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/LICENSE +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/benchmarks/mvnmle_bench.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/DESIGN.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/Forge.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/GPU_BACKEND_NOTES.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/Makefile +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/PYSTATSBIO_CONTEXT.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/_static/custom.css +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/anova.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/conf.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/core.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/descriptive.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/hypothesis.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/mixed.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/montecarlo.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/mvnmle.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/regression.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/docs/survival.rst +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/GPU_BACKEND_CONVENTION.md +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/_levene.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/_posthoc.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/_repeated.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/_ss.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/anova/solvers.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/capabilities.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/cholesky.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/determinant.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/qr.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/solve.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/linalg/svd.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/optimization/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/optimization/convergence.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/precision.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/timing.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/compute/tolerances.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/exceptions.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/protocols.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/result.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/core/validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/_missing.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/_quantile_types.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/descriptive/solvers.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_basis.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_fit.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_gcv.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/_smooth.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/backends/_gpu_family.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/gam/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/_design_factories.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/_p_adjust.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_chisq_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_fisher_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_ks_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_prop_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_t_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_var_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/_wilcox_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/hypothesis/solvers.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_deviance.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_pirls.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_pls.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_random_effects.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/_satterthwaite.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mixed/solvers.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/_ci.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/_influence.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/montecarlo/solvers.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/_likelihood.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multinomial/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/_factor.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/_rotation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/multivariate/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_monotone.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/base.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/gpu_fp32.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/gpu_fp64.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_objectives/parameterizations.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/_utils.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/_em_batched.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/_em_batched_np.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/_em_batched_patterns.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/_em_batched_torch.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/_squarem.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/em.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/datasets.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/mcar_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/patterns.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/mvnmle/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/_likelihood.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/ordinal/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/py.typed +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/_formatting.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/_glm.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/_linear.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/_nb_theta.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/backends/cpu_glm.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/backends/gpu_glm.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/families.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/regression/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/_cox.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/_discrete.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/_km.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/_logrank.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/backends/cpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/backends/gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/survival/solution.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_acf.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_factored.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_fit.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_forecast.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_kalman.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_likelihood.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_arima_order.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_common.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_decomposition.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_differencing.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_ets_forecast.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_ets_models.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/_stationarity.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/pystatistics/timeseries/backends/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_contrasts.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_design.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_factorial.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_levene.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_oneway.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_posthoc.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/anova/test_repeated_measures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/benchmark_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/core/test_exceptions.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/core/test_result.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/core/test_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_cor.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_cov.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_describe.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_missing.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_moments.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_quantile.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/descriptive/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_ancova_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_ancova_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_bonferroni_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_bonferroni_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_eta_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_eta_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_levene_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_levene_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_oneway_balanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_oneway_balanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_oneway_unbalanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_oneway_unbalanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_rm_mixed_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_rm_mixed_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_rm_within_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_rm_within_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_tukey_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_tukey_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_twoway_balanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_twoway_balanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_twoway_unbalanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/anova_twoway_unbalanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/basic_100x3.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/basic_100x3_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/basic_100x3_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/collinear_almost.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/collinear_almost_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/collinear_almost_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_basic_100x5.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_basic_100x5_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_basic_100x5_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_constant_column.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_constant_column_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_constant_column_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_extreme_values.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_extreme_values_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_extreme_values_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_large_1000x10.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_large_1000x10_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_large_1000x10_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_columnwise.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_columnwise_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_columnwise_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_scattered.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_scattered_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_nan_scattered_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_negative_correlation.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_negative_correlation_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_negative_correlation_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_perfect_correlation.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_perfect_correlation_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_perfect_correlation_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_single_column.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_single_column_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_single_column_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_ties.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_ties_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/desc_ties_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/different_scales.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/different_scales_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/different_scales_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_anova_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_descriptive_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_glm_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_hypothesis_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_mixed_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_montecarlo_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/generate_survival_fixtures.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_balanced.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_balanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_balanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_basic.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_basic_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_basic_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_large.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_large_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_large_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_separated.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_separated_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_binomial_separated_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_basic.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_basic_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_basic_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_large.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_large_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_gaussian_large_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_basic.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_basic_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_basic_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_large_counts.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_large_counts_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_large_counts_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_zeros.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_zeros_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/glm_poisson_zeros_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/high_noise.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/high_noise_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/high_noise_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_2x2_yates_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_2x2_yates_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_3x3_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_3x3_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_gof_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_gof_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_gof_unequal_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_chisq_gof_unequal_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_2x2_less_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_2x2_less_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_2x2_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_2x2_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_3x3_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_fisher_3x3_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_ks_onesample_norm_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_ks_onesample_norm_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_ks_twosample_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_ks_twosample_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_prop_onesample_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_prop_onesample_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_prop_twosample_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_prop_twosample_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_onesample_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_onesample_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_paired_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_paired_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_pooled_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_pooled_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_welch_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_t_welch_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_var_basic_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_var_basic_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_wilcox_ranksum_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_wilcox_ranksum_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_wilcox_signed_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/htest_wilcox_signed_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/ill_conditioned.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/ill_conditioned_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/ill_conditioned_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/large_coeffs.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/large_coeffs_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/large_coeffs_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_90_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_90_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_normal_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_normal_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_skewed_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_ci_skewed_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_mean_balanced_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_mean_balanced_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_mean_ordinary_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_mean_ordinary_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_median_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_median_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_variance_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_boot_variance_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_greater_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_greater_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_not_significant_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_not_significant_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_significant_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mc_perm_significant_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/glmm_binomial.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/glmm_poisson.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/lmm_crossed.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/lmm_intercept.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/lmm_ml.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/lmm_no_effect.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/lmm_slope.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/mixed_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/mixed/mixed_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/near_square.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/near_square_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/near_square_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/no_intercept.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/no_intercept_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/no_intercept_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_anova_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_descriptive_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_glm_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_hypothesis_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_mixed_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_montecarlo_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_survival_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_r_validation.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/run_validation.sh +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/small_noise.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/small_noise_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/small_noise_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_breslow_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_breslow_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_single_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_single_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_ties_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_ties_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_two_cov_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_cox_two_cov_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_basic_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_basic_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_heavy_cens_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_heavy_cens_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_loglog_ci_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_loglog_ci_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_no_cens_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_no_cens_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_plain_ci_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_plain_ci_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_ties_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_km_ties_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_peto_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_peto_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_three_group_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_three_group_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_two_group_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/surv_lr_two_group_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/tall_skinny.csv +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/tall_skinny_meta.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/tall_skinny_r_results.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/fixtures/validate_against_r.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/gam/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_chisq_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_design_split.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_fisher_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_ks_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_p_adjust.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_prop_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_t_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_var_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/hypothesis/test_wilcox_test.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_glmm.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_lmm_crossed.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_lmm_intercept.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_lmm_nested.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_lmm_slope.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_pls.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_random_effects.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mixed/test_satterthwaite.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_batched_solver.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_boot_ci.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_bootstrap.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_influence.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_permutation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/montecarlo/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/multinomial/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/multivariate/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/apple_em_reference.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/apple_reference.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/generate_em_fixtures.R +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_apple.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_complete.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_extreme.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_missvals.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_simple_mcar.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/little_mcar_summary.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/missvals_em_reference.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/missvals_reference.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/references/small_test_reference.json +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_em.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_mcar.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_mlest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_no_silent_fallback.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/mvnmle/test_squarem.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/ordinal/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/benchmark.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/benchmark.r +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_fit.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_gamma_nb.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_glm.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_glm_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_glm_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_module_split.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/regression/test_stress_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/conftest.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_coxph.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_discrete_time.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_gpu.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_kaplan_meier.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_logrank.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/survival/test_r_validation.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/test_code_quality.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/timeseries/__init__.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/timeseries/test_acf_stationarity.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/timeseries/test_decomposition.py +0 -0
- {pystatistics-3.0.1 → pystatistics-3.2.0}/tests/timeseries/test_ets.py +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
- **Apple Silicon (MPS) GPU support for FP32-capable backends.** The
|
|
13
|
+
`multinom`, `polr`, `gam`, and `arima`/`arima_batch` (Whittle) GPU
|
|
14
|
+
backends now run on Apple Silicon GPUs via `backend='gpu'`, using FP32
|
|
15
|
+
(MPS has no float64). Every operation on these paths is a native Metal
|
|
16
|
+
kernel — no silent CPU fallback. Results are validated against the CPU
|
|
17
|
+
reference at the `GPU_FP32` tolerance tier. `DataSource.to('mps')` now
|
|
18
|
+
works (float64 arrays are downcast to float32 on transfer, since MPS
|
|
19
|
+
has no float64). The CUDA FP64 path and its R-validation are unchanged.
|
|
20
|
+
- **`backend='auto'` never selects MPS.** On Apple Silicon, `'auto'`
|
|
21
|
+
routes to the CPU (FP64, R-validated) path; MPS is opt-in only via an
|
|
22
|
+
explicit `backend='gpu'`. This makes `multinom`/`polr`/`gam`/`arima`
|
|
23
|
+
consistent with the existing `regression` and `mvnmle` dispatch policy.
|
|
24
|
+
CUDA is still auto-selected.
|
|
25
|
+
- **PCA GPU remains CUDA-only by design.** PCA is fundamentally an
|
|
26
|
+
SVD / symmetric-eigendecomposition problem, and neither `linalg.svd`
|
|
27
|
+
(the `method='svd'` path) nor the eigendecomposition of `X'X` (the
|
|
28
|
+
`method='gram'` path) has a Metal kernel — both silently fall back to
|
|
29
|
+
the CPU on MPS. Rather than advertise a GPU path that isn't one,
|
|
30
|
+
`pca(backend='gpu')` now raises an actionable error on Apple Silicon
|
|
31
|
+
(use `backend='cpu'`, or `backend='auto'` which selects CPU on MPS).
|
|
32
|
+
- **MVN MLE GPU remains CUDA-only by design.** The EM algorithm's
|
|
33
|
+
iterative small-step + per-pattern scatter workload is far slower on
|
|
34
|
+
Metal than on the CPU, so `mlest(algorithm='em', backend='gpu')` now
|
|
35
|
+
raises an actionable error on Apple Silicon (use `backend='cpu'`, or
|
|
36
|
+
`backend='auto'` which routes to CPU). Direct (BFGS) GPU fitting is
|
|
37
|
+
unaffected.
|
|
38
|
+
- **Whittle ARIMA GPU FP32 convergence.** On the FP32 GPU path, an
|
|
39
|
+
L-BFGS-B `ABNORMAL_TERMINATION_IN_LNSRCH` at a stationary point (the
|
|
40
|
+
line search hitting the FP32 noise floor) is now accepted rather than
|
|
41
|
+
raised, matching the CPU fit at the `GPU_FP32` tier. The AR-stationarity
|
|
42
|
+
check still rejects genuinely bad optima. FP64 behaviour is unchanged.
|
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
Apple Silicon (MPS) GPU support for the FP32 backends, with honest,
|
|
6
|
+
fail-fast boundaries where Metal can't deliver a real GPU path.
|
|
7
|
+
|
|
8
|
+
- **GPU fitting now runs on Apple Silicon (MPS) for `multinom`, `polr`,
|
|
9
|
+
`gam`, and `arima` / `arima_batch` (Whittle).** Pass `backend='gpu'` on
|
|
10
|
+
a Mac with an Apple GPU to run these fits in FP32 on Metal. Every
|
|
11
|
+
operation on these paths is a native Metal kernel — there is no hidden
|
|
12
|
+
fallback to the CPU. Results match the CPU backend at the documented
|
|
13
|
+
GPU/FP32 tolerance tier. (MPS has no double precision, so `use_fp64=True`
|
|
14
|
+
is rejected on MPS; CUDA FP64 is unchanged.)
|
|
15
|
+
- **`DataSource.to('mps')`** now transfers arrays to the Apple GPU,
|
|
16
|
+
downcasting float64 to float32 (MPS has no float64). This lets you pay
|
|
17
|
+
the host→device copy once and reuse a device-resident `DataSource`
|
|
18
|
+
across multiple GPU fits, as with CUDA.
|
|
19
|
+
- **`backend='auto'` never selects MPS.** On Apple Silicon, `'auto'`
|
|
20
|
+
uses the CPU (double precision, the R-validated path); the Apple GPU is
|
|
21
|
+
opt-in only via an explicit `backend='gpu'`. CUDA continues to be
|
|
22
|
+
auto-selected. This matches how the regression and MVN MLE backends
|
|
23
|
+
already behaved.
|
|
24
|
+
- **PCA and MVN MLE GPU remain CUDA-only.** `pca(backend='gpu')` and
|
|
25
|
+
`mlest(algorithm='em', backend='gpu')` now raise a clear error on Apple
|
|
26
|
+
Silicon instead of running silently on the CPU under a `gpu` label: PCA
|
|
27
|
+
needs an SVD / eigendecomposition that Metal does not implement, and the
|
|
28
|
+
EM algorithm's iterative, small-step pattern is far slower on Metal than
|
|
29
|
+
on the CPU. Use `backend='cpu'` (or `backend='auto'`, which selects the
|
|
30
|
+
CPU on MPS). CUDA is supported for both. MVN MLE *direct* (BFGS) GPU
|
|
31
|
+
fitting is unaffected and works on MPS.
|
|
32
|
+
- **Whittle ARIMA GPU is more robust in FP32.** When the optimizer's line
|
|
33
|
+
search stalls at the FP32 noise floor on an already-converged fit, the
|
|
34
|
+
result is now accepted (it matches the CPU fit at the FP32 tier) instead
|
|
35
|
+
of raising a spurious convergence error. Non-stationary fits are still
|
|
36
|
+
rejected.
|
|
37
|
+
|
|
38
|
+
## 3.1.0
|
|
39
|
+
|
|
40
|
+
Categorical predictors and interaction terms in regression.
|
|
41
|
+
|
|
42
|
+
- **Factor support in `fit()` and `coxph()`.** Regression models can now
|
|
43
|
+
include categorical predictors and interaction terms, alongside the
|
|
44
|
+
existing numeric-matrix path. Describe the model with a list of *terms*
|
|
45
|
+
passed to `Design.from_datasource(..., terms=...)`:
|
|
46
|
+
|
|
47
|
+
- a bare column name is a numeric main effect,
|
|
48
|
+
- `C(name, ref=...)` is a categorical predictor (treatment/dummy coded,
|
|
49
|
+
expanding a *k*-level factor into *k−1* indicator columns), with a
|
|
50
|
+
selectable reference (baseline) level — the first level in sorted order
|
|
51
|
+
by default,
|
|
52
|
+
- a tuple of those is an interaction (numeric×numeric, numeric×categorical,
|
|
53
|
+
and categorical×categorical are all supported).
|
|
54
|
+
|
|
55
|
+
This works for ordinary least squares, every GLM family, and Cox
|
|
56
|
+
proportional hazards (which remains intercept-free). Expanded columns are
|
|
57
|
+
labeled `sex[M]`, `treatment[B]:sex[M]`, and `coef`, `standard_errors`,
|
|
58
|
+
the test statistic, and `p_values` stay aligned to those labels. Interaction
|
|
59
|
+
columns follow R's `model.matrix` ordering (the first factor varies
|
|
60
|
+
fastest), and design matrices and fitted coefficients match R's
|
|
61
|
+
`lm`/`glm`/`survival::coxph` for factors and interactions.
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from pystatistics import DataSource
|
|
65
|
+
from pystatistics.regression import Design, fit, C
|
|
66
|
+
|
|
67
|
+
ds = DataSource.from_dataframe(df)
|
|
68
|
+
design = Design.from_datasource(
|
|
69
|
+
ds, y="response",
|
|
70
|
+
terms=["age", C("sex", ref="F"), C("treatment", ref="A"),
|
|
71
|
+
(C("treatment", ref="A"), C("sex", ref="F"))],
|
|
72
|
+
)
|
|
73
|
+
result = fit(design) # family=… for GLMs
|
|
74
|
+
result.coef["treatment[B]:sex[M]"]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
New public symbol: `pystatistics.regression.C`.
|
|
78
|
+
|
|
79
|
+
- **`DataSource.from_dataframe` preserves non-numeric columns.** Numeric
|
|
80
|
+
columns are still stored as float64; string/object/categorical columns are
|
|
81
|
+
now retained as-is instead of being force-cast (which previously raised on
|
|
82
|
+
string columns). These are the inputs encoded by `C(...)`.
|
|
83
|
+
|
|
84
|
+
- **ETS now converges on (near-)perfectly-fit series.** The Gaussian
|
|
85
|
+
likelihood's variance floor is now relative to the data scale rather than a
|
|
86
|
+
fixed `1e-30`. On a noiseless or near-noiseless series the residual variance
|
|
87
|
+
no longer drives the objective toward an unbounded optimum, so the optimiser
|
|
88
|
+
reports convergence instead of an abnormal line-search termination. Fits on
|
|
89
|
+
ordinary (noisy) series are numerically unchanged.
|
|
90
|
+
|
|
3
91
|
## 3.0.1
|
|
4
92
|
|
|
5
93
|
Metadata and documentation polish. No API changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystatistics
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.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/
|
|
@@ -208,6 +208,27 @@ y_binary = (X @ [1, -1, 0.5, 0, 0] + np.random.randn(1000) > 0).astype(float)
|
|
|
208
208
|
result = fit(X, y_binary, family='binomial')
|
|
209
209
|
print(result.summary())
|
|
210
210
|
|
|
211
|
+
# --- Categorical predictors & interactions ---
|
|
212
|
+
# Describe a model as a list of terms (no R-style formula strings):
|
|
213
|
+
# "name" -> numeric main effect
|
|
214
|
+
# C(name, ref=…) -> categorical, treatment-coded with a chosen baseline
|
|
215
|
+
# (a, b) -> interaction (numeric and/or categorical)
|
|
216
|
+
from pystatistics import DataSource
|
|
217
|
+
from pystatistics.regression import Design, fit, C
|
|
218
|
+
|
|
219
|
+
ds = DataSource.from_dataframe(df) # df has age, sex, treatment, response
|
|
220
|
+
design = Design.from_datasource(
|
|
221
|
+
ds, y='response',
|
|
222
|
+
terms=['age', C('sex', ref='F'), C('treatment', ref='A'),
|
|
223
|
+
(C('treatment', ref='A'), C('sex', ref='F'))],
|
|
224
|
+
)
|
|
225
|
+
result = fit(design) # also works with family=… for GLMs
|
|
226
|
+
print(result.coef['treatment[B]:sex[M]']) # interaction coefficient
|
|
227
|
+
|
|
228
|
+
# Cox PH takes the same spec (no intercept):
|
|
229
|
+
from pystatistics.survival import coxph
|
|
230
|
+
cox = coxph(time, event, ds, terms=['age', C('sex', ref='F')])
|
|
231
|
+
|
|
211
232
|
# GPU acceleration (any model)
|
|
212
233
|
result = fit(X, y, backend='gpu')
|
|
213
234
|
|
|
@@ -370,6 +391,39 @@ pip install pystatistics[dev]
|
|
|
370
391
|
|
|
371
392
|
## What's New
|
|
372
393
|
|
|
394
|
+
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
395
|
+
|
|
396
|
+
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
397
|
+
on Apple Silicon GPUs with `backend='gpu'`, in FP32 and entirely on
|
|
398
|
+
native Metal kernels (no hidden CPU fallback). Results match the CPU
|
|
399
|
+
backend at the GPU/FP32 tolerance tier.
|
|
400
|
+
- `DataSource.to('mps')` transfers data to the Apple GPU (float64 →
|
|
401
|
+
float32), so you can pay the host→device copy once and reuse it across
|
|
402
|
+
fits.
|
|
403
|
+
- `backend='auto'` uses the CPU on Apple Silicon; the Apple GPU is opt-in
|
|
404
|
+
via an explicit `backend='gpu'`. CUDA is still auto-selected.
|
|
405
|
+
- `pca` and MVN MLE `em` GPU paths remain CUDA-only and now raise a clear
|
|
406
|
+
error on Apple Silicon rather than silently running on the CPU — PCA's
|
|
407
|
+
SVD/eigendecomposition and the EM scatter/iteration pattern have no
|
|
408
|
+
efficient Metal equivalent. Use `backend='cpu'` or `'auto'` on a Mac.
|
|
409
|
+
(MVN MLE *direct* GPU fitting works on MPS.)
|
|
410
|
+
- Whittle ARIMA GPU fits no longer raise a spurious convergence error when
|
|
411
|
+
the FP32 line search stalls at an already-converged optimum.
|
|
412
|
+
|
|
413
|
+
### 3.1.0 — Categorical predictors & interaction terms
|
|
414
|
+
|
|
415
|
+
- Regression now supports categorical predictors and interactions via a
|
|
416
|
+
`terms=` spec on `Design.from_datasource`: bare names are numeric main
|
|
417
|
+
effects, `C(name, ref=...)` marks a categorical predictor with a selectable
|
|
418
|
+
baseline level, and tuples express interactions (numeric and/or
|
|
419
|
+
categorical). Works for OLS, all GLM families, and Cox PH (no intercept).
|
|
420
|
+
- Expanded columns are labeled `sex[M]`, `treatment[B]:sex[M]`, with `coef`
|
|
421
|
+
and inference outputs aligned to those labels. Design matrices match R's
|
|
422
|
+
`model.matrix` for factors and interactions.
|
|
423
|
+
- `DataSource.from_dataframe` now keeps non-numeric columns as-is (previously
|
|
424
|
+
force-cast to float), so categorical columns can feed `C(...)`.
|
|
425
|
+
- New public symbol: `pystatistics.regression.C`.
|
|
426
|
+
|
|
373
427
|
### 3.0.1 — Metadata and documentation polish
|
|
374
428
|
|
|
375
429
|
- Development Status classifier bumped from Alpha to Production/Stable.
|
|
@@ -161,6 +161,27 @@ y_binary = (X @ [1, -1, 0.5, 0, 0] + np.random.randn(1000) > 0).astype(float)
|
|
|
161
161
|
result = fit(X, y_binary, family='binomial')
|
|
162
162
|
print(result.summary())
|
|
163
163
|
|
|
164
|
+
# --- Categorical predictors & interactions ---
|
|
165
|
+
# Describe a model as a list of terms (no R-style formula strings):
|
|
166
|
+
# "name" -> numeric main effect
|
|
167
|
+
# C(name, ref=…) -> categorical, treatment-coded with a chosen baseline
|
|
168
|
+
# (a, b) -> interaction (numeric and/or categorical)
|
|
169
|
+
from pystatistics import DataSource
|
|
170
|
+
from pystatistics.regression import Design, fit, C
|
|
171
|
+
|
|
172
|
+
ds = DataSource.from_dataframe(df) # df has age, sex, treatment, response
|
|
173
|
+
design = Design.from_datasource(
|
|
174
|
+
ds, y='response',
|
|
175
|
+
terms=['age', C('sex', ref='F'), C('treatment', ref='A'),
|
|
176
|
+
(C('treatment', ref='A'), C('sex', ref='F'))],
|
|
177
|
+
)
|
|
178
|
+
result = fit(design) # also works with family=… for GLMs
|
|
179
|
+
print(result.coef['treatment[B]:sex[M]']) # interaction coefficient
|
|
180
|
+
|
|
181
|
+
# Cox PH takes the same spec (no intercept):
|
|
182
|
+
from pystatistics.survival import coxph
|
|
183
|
+
cox = coxph(time, event, ds, terms=['age', C('sex', ref='F')])
|
|
184
|
+
|
|
164
185
|
# GPU acceleration (any model)
|
|
165
186
|
result = fit(X, y, backend='gpu')
|
|
166
187
|
|
|
@@ -323,6 +344,39 @@ pip install pystatistics[dev]
|
|
|
323
344
|
|
|
324
345
|
## What's New
|
|
325
346
|
|
|
347
|
+
### 3.2.0 — Apple Silicon (MPS) GPU support
|
|
348
|
+
|
|
349
|
+
- `multinom`, `polr`, `gam`, and `arima` / `arima_batch` (Whittle) now run
|
|
350
|
+
on Apple Silicon GPUs with `backend='gpu'`, in FP32 and entirely on
|
|
351
|
+
native Metal kernels (no hidden CPU fallback). Results match the CPU
|
|
352
|
+
backend at the GPU/FP32 tolerance tier.
|
|
353
|
+
- `DataSource.to('mps')` transfers data to the Apple GPU (float64 →
|
|
354
|
+
float32), so you can pay the host→device copy once and reuse it across
|
|
355
|
+
fits.
|
|
356
|
+
- `backend='auto'` uses the CPU on Apple Silicon; the Apple GPU is opt-in
|
|
357
|
+
via an explicit `backend='gpu'`. CUDA is still auto-selected.
|
|
358
|
+
- `pca` and MVN MLE `em` GPU paths remain CUDA-only and now raise a clear
|
|
359
|
+
error on Apple Silicon rather than silently running on the CPU — PCA's
|
|
360
|
+
SVD/eigendecomposition and the EM scatter/iteration pattern have no
|
|
361
|
+
efficient Metal equivalent. Use `backend='cpu'` or `'auto'` on a Mac.
|
|
362
|
+
(MVN MLE *direct* GPU fitting works on MPS.)
|
|
363
|
+
- Whittle ARIMA GPU fits no longer raise a spurious convergence error when
|
|
364
|
+
the FP32 line search stalls at an already-converged optimum.
|
|
365
|
+
|
|
366
|
+
### 3.1.0 — Categorical predictors & interaction terms
|
|
367
|
+
|
|
368
|
+
- Regression now supports categorical predictors and interactions via a
|
|
369
|
+
`terms=` spec on `Design.from_datasource`: bare names are numeric main
|
|
370
|
+
effects, `C(name, ref=...)` marks a categorical predictor with a selectable
|
|
371
|
+
baseline level, and tuples express interactions (numeric and/or
|
|
372
|
+
categorical). Works for OLS, all GLM families, and Cox PH (no intercept).
|
|
373
|
+
- Expanded columns are labeled `sex[M]`, `treatment[B]:sex[M]`, with `coef`
|
|
374
|
+
and inference outputs aligned to those labels. Design matrices match R's
|
|
375
|
+
`model.matrix` for factors and interactions.
|
|
376
|
+
- `DataSource.from_dataframe` now keeps non-numeric columns as-is (previously
|
|
377
|
+
force-cast to float), so categorical columns can feed `C(...)`.
|
|
378
|
+
- New public symbol: `pystatistics.regression.C`.
|
|
379
|
+
|
|
326
380
|
### 3.0.1 — Metadata and documentation polish
|
|
327
381
|
|
|
328
382
|
- Development Status classifier bumped from Alpha to Production/Stable.
|
|
@@ -114,6 +114,25 @@ Shared infrastructure lives in `core/`: DataSource, Result[P], device detection,
|
|
|
114
114
|
- **GPU applicability**: MODERATE — depends on specific methods; Kalman filtering has sequential dependencies but spectral analysis parallelizes well
|
|
115
115
|
- **R validation**: `arima()`, `forecast` package
|
|
116
116
|
|
|
117
|
+
#### Demand-driven primitives (pulled in when a domain vertical needs them)
|
|
118
|
+
|
|
119
|
+
These are genuinely general-purpose primitives identified while scoping the
|
|
120
|
+
`pystats[domain]` libraries (clinical / genomic / finance / insurance). They
|
|
121
|
+
belong here rather than in any single domain library because **≥2 separate
|
|
122
|
+
domains share the exact same underlying mechanic** (the promotion rule). But
|
|
123
|
+
they are specialized enough that they are **not worth implementing in isolation**
|
|
124
|
+
— we implement each one *when the first domain vertical actually needs it*, then
|
|
125
|
+
that domain pegs the new `pystatistics` version. Until then they stay on this
|
|
126
|
+
list as candidates, not commitments.
|
|
127
|
+
|
|
128
|
+
- [ ] **Parametric distribution fitting (`fitdist`)** — MLE fit of common
|
|
129
|
+
parametric distributions (lognormal, gamma, Pareto, Weibull, …) with
|
|
130
|
+
goodness-of-fit. *Shared by:* insurance severity modeling, finance
|
|
131
|
+
parametric return/loss distributions. **Priority**: ON-DEMAND.
|
|
132
|
+
- [ ] **Extreme-value theory / peaks-over-threshold (GPD)** — generalized Pareto
|
|
133
|
+
tail fitting and tail-quantile estimation. *Shared by:* finance tail risk,
|
|
134
|
+
insurance large-loss modeling. **Priority**: ON-DEMAND.
|
|
135
|
+
|
|
117
136
|
---
|
|
118
137
|
|
|
119
138
|
## Implementation Priority
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Ordinal Regression
|
|
2
|
+
==================
|
|
3
|
+
|
|
4
|
+
Proportional odds (cumulative link) models matching R's ``MASS::polr()``. Supports logistic, probit, and complementary log-log links.
|
|
5
|
+
|
|
6
|
+
.. automodule:: pystatistics.ordinal
|
|
7
|
+
:members:
|
|
8
|
+
:undoc-members:
|
|
9
|
+
:show-inheritance:
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ANOVA contrast coding — re-export shim.
|
|
3
|
+
|
|
4
|
+
The categorical-encoding engine is shared library-wide and lives in
|
|
5
|
+
``pystatistics.core.encoding`` (used by both ANOVA and regression). ANOVA
|
|
6
|
+
historically refers to these operations with R's "contrast" vocabulary, so
|
|
7
|
+
this module re-exports the engine under the legacy ANOVA-facing names:
|
|
8
|
+
|
|
9
|
+
encode_treatment -> encode_dummy
|
|
10
|
+
build_model_matrix -> build_design_matrix
|
|
11
|
+
ModelMatrix -> DesignMatrix
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from pystatistics.core.encoding import (
|
|
15
|
+
DesignMatrix as ModelMatrix,
|
|
16
|
+
build_design_matrix as build_model_matrix,
|
|
17
|
+
encode_deviation,
|
|
18
|
+
encode_dummy as encode_treatment,
|
|
19
|
+
interaction_columns,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"ModelMatrix",
|
|
24
|
+
"build_model_matrix",
|
|
25
|
+
"encode_deviation",
|
|
26
|
+
"encode_treatment",
|
|
27
|
+
"interaction_columns",
|
|
28
|
+
]
|
|
@@ -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()
|
|
@@ -197,11 +197,24 @@ class DataSource:
|
|
|
197
197
|
|
|
198
198
|
@classmethod
|
|
199
199
|
def from_dataframe(cls, df: 'pd.DataFrame', *, source_path: str | None = None) -> DataSource:
|
|
200
|
-
"""Construct from pandas DataFrame.
|
|
200
|
+
"""Construct from pandas DataFrame.
|
|
201
|
+
|
|
202
|
+
Numeric columns are stored as float64. Non-numeric columns (strings,
|
|
203
|
+
objects, pandas categoricals) are preserved as-is rather than being
|
|
204
|
+
force-cast — they are the raw material for categorical predictors,
|
|
205
|
+
which the regression term builder encodes via C(...). Force-casting
|
|
206
|
+
them to float would either crash or silently corrupt the data.
|
|
207
|
+
"""
|
|
208
|
+
import pandas as pd
|
|
209
|
+
|
|
201
210
|
storage: dict[str, Any] = {}
|
|
202
|
-
|
|
211
|
+
|
|
203
212
|
for col in df.columns:
|
|
204
|
-
|
|
213
|
+
series = df[col]
|
|
214
|
+
if pd.api.types.is_numeric_dtype(series):
|
|
215
|
+
storage[col] = series.to_numpy(dtype=np.float64)
|
|
216
|
+
else:
|
|
217
|
+
storage[col] = series.to_numpy()
|
|
205
218
|
|
|
206
219
|
metadata = {
|
|
207
220
|
'n_observations': len(df),
|
|
@@ -372,11 +385,19 @@ class DataSource:
|
|
|
372
385
|
else:
|
|
373
386
|
# Coerce numpy→torch on device; move torch to device.
|
|
374
387
|
if isinstance(value, torch.Tensor):
|
|
375
|
-
|
|
388
|
+
tensor = value
|
|
376
389
|
elif isinstance(value, np.ndarray):
|
|
377
|
-
|
|
390
|
+
tensor = torch.as_tensor(value)
|
|
378
391
|
else:
|
|
379
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)
|
|
380
401
|
|
|
381
402
|
capabilities = {CAPABILITY_MATERIALIZED, CAPABILITY_REPEATABLE}
|
|
382
403
|
if target_is_gpu:
|