pystatistics 3.3.0__tar.gz → 3.4.1__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.
Files changed (588) hide show
  1. pystatistics-3.4.1/.release/UNRELEASED.md +23 -0
  2. {pystatistics-3.3.0 → pystatistics-3.4.1}/CHANGELOG.md +33 -0
  3. {pystatistics-3.3.0 → pystatistics-3.4.1}/PKG-INFO +22 -2
  4. {pystatistics-3.3.0 → pystatistics-3.4.1}/README.md +21 -1
  5. {pystatistics-3.3.0 → pystatistics-3.4.1}/pyproject.toml +1 -1
  6. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/__init__.py +1 -1
  7. pystatistics-3.4.1/pystatistics/mice/backends/_gpu_linreg.py +138 -0
  8. pystatistics-3.4.1/pystatistics/mice/backends/_gpu_methods.py +81 -0
  9. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/backends/cpu.py +7 -4
  10. pystatistics-3.4.1/pystatistics/mice/backends/gpu.py +170 -0
  11. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/pmm.py +32 -11
  12. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/solvers.py +36 -20
  13. pystatistics-3.4.1/tests/mice/test_gpu.py +146 -0
  14. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_methods.py +29 -0
  15. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_mice.py +16 -3
  16. pystatistics-3.3.0/.release/UNRELEASED.md +0 -30
  17. {pystatistics-3.3.0 → pystatistics-3.4.1}/.github/workflows/publish.yml +0 -0
  18. {pystatistics-3.3.0 → pystatistics-3.4.1}/.github/workflows/trigger-docs-rebuild.yml +0 -0
  19. {pystatistics-3.3.0 → pystatistics-3.4.1}/.gitignore +0 -0
  20. {pystatistics-3.3.0 → pystatistics-3.4.1}/.release/CHECKLIST.md +0 -0
  21. {pystatistics-3.3.0 → pystatistics-3.4.1}/.release/release.py +0 -0
  22. {pystatistics-3.3.0 → pystatistics-3.4.1}/CLAUDE.md +0 -0
  23. {pystatistics-3.3.0 → pystatistics-3.4.1}/LICENSE +0 -0
  24. {pystatistics-3.3.0 → pystatistics-3.4.1}/benchmarks/mvnmle_bench.py +0 -0
  25. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/DESIGN.md +0 -0
  26. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/Forge.md +0 -0
  27. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/GPU_BACKEND_NOTES.md +0 -0
  28. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/Makefile +0 -0
  29. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/PYSTATSBIO_CONTEXT.md +0 -0
  30. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/ROADMAP.md +0 -0
  31. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/_static/custom.css +0 -0
  32. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/anova.rst +0 -0
  33. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/conf.py +0 -0
  34. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/core.rst +0 -0
  35. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/descriptive.rst +0 -0
  36. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/gam.rst +0 -0
  37. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/hypothesis.rst +0 -0
  38. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/index.rst +0 -0
  39. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/mixed.rst +0 -0
  40. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/montecarlo.rst +0 -0
  41. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/multinomial.rst +0 -0
  42. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/multivariate.rst +0 -0
  43. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/mvnmle.rst +0 -0
  44. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/ordinal.rst +0 -0
  45. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/regression.rst +0 -0
  46. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/survival.rst +0 -0
  47. {pystatistics-3.3.0 → pystatistics-3.4.1}/docs/timeseries.rst +0 -0
  48. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/GPU_BACKEND_CONVENTION.md +0 -0
  49. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/__init__.py +0 -0
  50. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_common.py +0 -0
  51. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_contrasts.py +0 -0
  52. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_levene.py +0 -0
  53. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_posthoc.py +0 -0
  54. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_repeated.py +0 -0
  55. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/_ss.py +0 -0
  56. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/design.py +0 -0
  57. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/solution.py +0 -0
  58. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/anova/solvers.py +0 -0
  59. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/__init__.py +0 -0
  60. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/capabilities.py +0 -0
  61. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/__init__.py +0 -0
  62. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/device.py +0 -0
  63. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/__init__.py +0 -0
  64. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/batched.py +0 -0
  65. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/cholesky.py +0 -0
  66. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/determinant.py +0 -0
  67. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/qr.py +0 -0
  68. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/solve.py +0 -0
  69. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/linalg/svd.py +0 -0
  70. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/optimization/__init__.py +0 -0
  71. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/optimization/convergence.py +0 -0
  72. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/precision.py +0 -0
  73. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/timing.py +0 -0
  74. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/tolerances.py +0 -0
  75. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/compute/torch_interop.py +0 -0
  76. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/datasource.py +0 -0
  77. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/encoding.py +0 -0
  78. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/exceptions.py +0 -0
  79. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/protocols.py +0 -0
  80. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/result.py +0 -0
  81. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/core/validation.py +0 -0
  82. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/__init__.py +0 -0
  83. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/_missing.py +0 -0
  84. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/_quantile_types.py +0 -0
  85. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/backends/__init__.py +0 -0
  86. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/backends/cpu.py +0 -0
  87. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/backends/gpu.py +0 -0
  88. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/design.py +0 -0
  89. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/solution.py +0 -0
  90. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/descriptive/solvers.py +0 -0
  91. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/__init__.py +0 -0
  92. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_basis.py +0 -0
  93. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_common.py +0 -0
  94. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_fit.py +0 -0
  95. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_gam.py +0 -0
  96. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_gcv.py +0 -0
  97. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/_smooth.py +0 -0
  98. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/backends/__init__.py +0 -0
  99. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/backends/_gpu_family.py +0 -0
  100. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/backends/gpu_pirls.py +0 -0
  101. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/gam/solution.py +0 -0
  102. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/__init__.py +0 -0
  103. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/_common.py +0 -0
  104. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/_design_factories.py +0 -0
  105. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/_p_adjust.py +0 -0
  106. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/__init__.py +0 -0
  107. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_chisq_test.py +0 -0
  108. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_fisher_test.py +0 -0
  109. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_ks_test.py +0 -0
  110. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_prop_test.py +0 -0
  111. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_t_test.py +0 -0
  112. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_var_test.py +0 -0
  113. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/_wilcox_test.py +0 -0
  114. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/cpu.py +0 -0
  115. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/backends/gpu.py +0 -0
  116. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/design.py +0 -0
  117. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/solution.py +0 -0
  118. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/hypothesis/solvers.py +0 -0
  119. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/__init__.py +0 -0
  120. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/_chain.py +0 -0
  121. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/_rng.py +0 -0
  122. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/_visit.py +0 -0
  123. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/backends/__init__.py +0 -0
  124. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/datasets.py +0 -0
  125. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/design.py +0 -0
  126. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/__init__.py +0 -0
  127. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/_linreg.py +0 -0
  128. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/base.py +0 -0
  129. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/norm.py +0 -0
  130. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/methods/registry.py +0 -0
  131. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/pooling.py +0 -0
  132. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mice/solution.py +0 -0
  133. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/__init__.py +0 -0
  134. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_common.py +0 -0
  135. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_deviance.py +0 -0
  136. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_pirls.py +0 -0
  137. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_pls.py +0 -0
  138. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_random_effects.py +0 -0
  139. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/_satterthwaite.py +0 -0
  140. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/design.py +0 -0
  141. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/solution.py +0 -0
  142. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mixed/solvers.py +0 -0
  143. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/__init__.py +0 -0
  144. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/_ci.py +0 -0
  145. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/_common.py +0 -0
  146. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/_influence.py +0 -0
  147. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/backends/__init__.py +0 -0
  148. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/backends/cpu.py +0 -0
  149. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/backends/gpu.py +0 -0
  150. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/design.py +0 -0
  151. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/solution.py +0 -0
  152. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/montecarlo/solvers.py +0 -0
  153. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/__init__.py +0 -0
  154. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/_common.py +0 -0
  155. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/_likelihood.py +0 -0
  156. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/_solver.py +0 -0
  157. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/backends/__init__.py +0 -0
  158. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/backends/gpu_likelihood.py +0 -0
  159. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multinomial/solution.py +0 -0
  160. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/__init__.py +0 -0
  161. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/_common.py +0 -0
  162. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/_factor.py +0 -0
  163. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/_pca.py +0 -0
  164. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/_rotation.py +0 -0
  165. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/backends/__init__.py +0 -0
  166. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/multivariate/backends/gpu_pca.py +0 -0
  167. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/__init__.py +0 -0
  168. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_monotone.py +0 -0
  169. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/__init__.py +0 -0
  170. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/base.py +0 -0
  171. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/cpu.py +0 -0
  172. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/gpu_fp32.py +0 -0
  173. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/gpu_fp64.py +0 -0
  174. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_objectives/parameterizations.py +0 -0
  175. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/_utils.py +0 -0
  176. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/__init__.py +0 -0
  177. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/_em_batched.py +0 -0
  178. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/_em_batched_np.py +0 -0
  179. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/_em_batched_patterns.py +0 -0
  180. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/_em_batched_torch.py +0 -0
  181. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/_squarem.py +0 -0
  182. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/cpu.py +0 -0
  183. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/em.py +0 -0
  184. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/backends/gpu.py +0 -0
  185. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/datasets.py +0 -0
  186. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/design.py +0 -0
  187. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/mcar_test.py +0 -0
  188. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/patterns.py +0 -0
  189. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/solution.py +0 -0
  190. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/mvnmle/solvers.py +0 -0
  191. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/__init__.py +0 -0
  192. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/_common.py +0 -0
  193. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/_likelihood.py +0 -0
  194. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/_solver.py +0 -0
  195. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/backends/__init__.py +0 -0
  196. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/backends/gpu_likelihood.py +0 -0
  197. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/ordinal/solution.py +0 -0
  198. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/py.typed +0 -0
  199. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/__init__.py +0 -0
  200. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/_formatting.py +0 -0
  201. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/_glm.py +0 -0
  202. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/_linear.py +0 -0
  203. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/_nb_theta.py +0 -0
  204. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/backends/__init__.py +0 -0
  205. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/backends/cpu.py +0 -0
  206. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/backends/cpu_glm.py +0 -0
  207. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/backends/gpu.py +0 -0
  208. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/backends/gpu_glm.py +0 -0
  209. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/design.py +0 -0
  210. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/families.py +0 -0
  211. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/solution.py +0 -0
  212. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/solvers.py +0 -0
  213. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/regression/terms.py +0 -0
  214. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/__init__.py +0 -0
  215. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/_common.py +0 -0
  216. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/_cox.py +0 -0
  217. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/_discrete.py +0 -0
  218. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/_km.py +0 -0
  219. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/_logrank.py +0 -0
  220. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/backends/__init__.py +0 -0
  221. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/backends/cpu.py +0 -0
  222. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/backends/gpu.py +0 -0
  223. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/design.py +0 -0
  224. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/solution.py +0 -0
  225. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/survival/solvers.py +0 -0
  226. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/__init__.py +0 -0
  227. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_acf.py +0 -0
  228. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_batch.py +0 -0
  229. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_factored.py +0 -0
  230. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_fit.py +0 -0
  231. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_forecast.py +0 -0
  232. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_kalman.py +0 -0
  233. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_likelihood.py +0 -0
  234. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_arima_order.py +0 -0
  235. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_common.py +0 -0
  236. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_decomposition.py +0 -0
  237. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_differencing.py +0 -0
  238. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_ets_fit.py +0 -0
  239. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_ets_forecast.py +0 -0
  240. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_ets_models.py +0 -0
  241. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_stationarity.py +0 -0
  242. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/_whittle.py +0 -0
  243. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/backends/__init__.py +0 -0
  244. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/backends/whittle_batch_gpu.py +0 -0
  245. {pystatistics-3.3.0 → pystatistics-3.4.1}/pystatistics/timeseries/backends/whittle_gpu.py +0 -0
  246. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/__init__.py +0 -0
  247. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/conftest.py +0 -0
  248. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_contrasts.py +0 -0
  249. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_design.py +0 -0
  250. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_factorial.py +0 -0
  251. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_levene.py +0 -0
  252. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_oneway.py +0 -0
  253. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_posthoc.py +0 -0
  254. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_r_validation.py +0 -0
  255. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/anova/test_repeated_measures.py +0 -0
  256. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/benchmark_gpu.py +0 -0
  257. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/conftest.py +0 -0
  258. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/core/test_datasource.py +0 -0
  259. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/core/test_exceptions.py +0 -0
  260. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/core/test_result.py +0 -0
  261. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/core/test_torch_interop.py +0 -0
  262. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/core/test_validation.py +0 -0
  263. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/__init__.py +0 -0
  264. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/conftest.py +0 -0
  265. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_cor.py +0 -0
  266. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_cov.py +0 -0
  267. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_describe.py +0 -0
  268. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_gpu.py +0 -0
  269. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_missing.py +0 -0
  270. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_moments.py +0 -0
  271. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_quantile.py +0 -0
  272. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/descriptive/test_r_validation.py +0 -0
  273. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_ancova_meta.json +0 -0
  274. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_ancova_r_results.json +0 -0
  275. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_bonferroni_meta.json +0 -0
  276. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_bonferroni_r_results.json +0 -0
  277. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_eta_meta.json +0 -0
  278. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_eta_r_results.json +0 -0
  279. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_levene_meta.json +0 -0
  280. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_levene_r_results.json +0 -0
  281. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_oneway_balanced_meta.json +0 -0
  282. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_oneway_balanced_r_results.json +0 -0
  283. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_oneway_unbalanced_meta.json +0 -0
  284. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_oneway_unbalanced_r_results.json +0 -0
  285. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_rm_mixed_meta.json +0 -0
  286. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_rm_mixed_r_results.json +0 -0
  287. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_rm_within_meta.json +0 -0
  288. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_rm_within_r_results.json +0 -0
  289. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_tukey_meta.json +0 -0
  290. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_tukey_r_results.json +0 -0
  291. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_twoway_balanced_meta.json +0 -0
  292. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_twoway_balanced_r_results.json +0 -0
  293. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_twoway_unbalanced_meta.json +0 -0
  294. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/anova_twoway_unbalanced_r_results.json +0 -0
  295. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/basic_100x3.csv +0 -0
  296. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/basic_100x3_meta.json +0 -0
  297. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/basic_100x3_r_results.json +0 -0
  298. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/collinear_almost.csv +0 -0
  299. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/collinear_almost_meta.json +0 -0
  300. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/collinear_almost_r_results.json +0 -0
  301. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_basic_100x5.csv +0 -0
  302. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_basic_100x5_meta.json +0 -0
  303. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_basic_100x5_r_results.json +0 -0
  304. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_constant_column.csv +0 -0
  305. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_constant_column_meta.json +0 -0
  306. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_constant_column_r_results.json +0 -0
  307. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_extreme_values.csv +0 -0
  308. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_extreme_values_meta.json +0 -0
  309. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_extreme_values_r_results.json +0 -0
  310. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_large_1000x10.csv +0 -0
  311. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_large_1000x10_meta.json +0 -0
  312. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_large_1000x10_r_results.json +0 -0
  313. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_columnwise.csv +0 -0
  314. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_columnwise_meta.json +0 -0
  315. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_columnwise_r_results.json +0 -0
  316. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_scattered.csv +0 -0
  317. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_scattered_meta.json +0 -0
  318. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_nan_scattered_r_results.json +0 -0
  319. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_negative_correlation.csv +0 -0
  320. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_negative_correlation_meta.json +0 -0
  321. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_negative_correlation_r_results.json +0 -0
  322. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_perfect_correlation.csv +0 -0
  323. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_perfect_correlation_meta.json +0 -0
  324. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_perfect_correlation_r_results.json +0 -0
  325. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_single_column.csv +0 -0
  326. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_single_column_meta.json +0 -0
  327. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_single_column_r_results.json +0 -0
  328. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_ties.csv +0 -0
  329. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_ties_meta.json +0 -0
  330. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/desc_ties_r_results.json +0 -0
  331. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/different_scales.csv +0 -0
  332. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/different_scales_meta.json +0 -0
  333. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/different_scales_r_results.json +0 -0
  334. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_anova_fixtures.py +0 -0
  335. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_descriptive_fixtures.py +0 -0
  336. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_fixtures.py +0 -0
  337. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_glm_fixtures.py +0 -0
  338. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_hypothesis_fixtures.py +0 -0
  339. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_mixed_fixtures.py +0 -0
  340. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_montecarlo_fixtures.py +0 -0
  341. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/generate_survival_fixtures.py +0 -0
  342. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_balanced.csv +0 -0
  343. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_balanced_meta.json +0 -0
  344. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_balanced_r_results.json +0 -0
  345. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_basic.csv +0 -0
  346. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_basic_meta.json +0 -0
  347. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_basic_r_results.json +0 -0
  348. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_large.csv +0 -0
  349. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_large_meta.json +0 -0
  350. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_large_r_results.json +0 -0
  351. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_separated.csv +0 -0
  352. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_separated_meta.json +0 -0
  353. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_binomial_separated_r_results.json +0 -0
  354. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_basic.csv +0 -0
  355. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_basic_meta.json +0 -0
  356. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_basic_r_results.json +0 -0
  357. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_large.csv +0 -0
  358. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_large_meta.json +0 -0
  359. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_gaussian_large_r_results.json +0 -0
  360. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_basic.csv +0 -0
  361. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_basic_meta.json +0 -0
  362. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_basic_r_results.json +0 -0
  363. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_large_counts.csv +0 -0
  364. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_large_counts_meta.json +0 -0
  365. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_large_counts_r_results.json +0 -0
  366. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_zeros.csv +0 -0
  367. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_zeros_meta.json +0 -0
  368. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/glm_poisson_zeros_r_results.json +0 -0
  369. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/high_noise.csv +0 -0
  370. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/high_noise_meta.json +0 -0
  371. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/high_noise_r_results.json +0 -0
  372. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_2x2_yates_meta.json +0 -0
  373. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_2x2_yates_r_results.json +0 -0
  374. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_3x3_meta.json +0 -0
  375. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_3x3_r_results.json +0 -0
  376. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_gof_meta.json +0 -0
  377. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_gof_r_results.json +0 -0
  378. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_gof_unequal_meta.json +0 -0
  379. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_chisq_gof_unequal_r_results.json +0 -0
  380. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_2x2_less_meta.json +0 -0
  381. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_2x2_less_r_results.json +0 -0
  382. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_2x2_meta.json +0 -0
  383. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_2x2_r_results.json +0 -0
  384. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_3x3_meta.json +0 -0
  385. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_fisher_3x3_r_results.json +0 -0
  386. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_ks_onesample_norm_meta.json +0 -0
  387. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_ks_onesample_norm_r_results.json +0 -0
  388. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_ks_twosample_meta.json +0 -0
  389. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_ks_twosample_r_results.json +0 -0
  390. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_prop_onesample_meta.json +0 -0
  391. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_prop_onesample_r_results.json +0 -0
  392. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_prop_twosample_meta.json +0 -0
  393. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_prop_twosample_r_results.json +0 -0
  394. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_onesample_meta.json +0 -0
  395. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_onesample_r_results.json +0 -0
  396. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_paired_meta.json +0 -0
  397. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_paired_r_results.json +0 -0
  398. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_pooled_meta.json +0 -0
  399. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_pooled_r_results.json +0 -0
  400. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_welch_meta.json +0 -0
  401. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_t_welch_r_results.json +0 -0
  402. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_var_basic_meta.json +0 -0
  403. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_var_basic_r_results.json +0 -0
  404. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_wilcox_ranksum_meta.json +0 -0
  405. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_wilcox_ranksum_r_results.json +0 -0
  406. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_wilcox_signed_meta.json +0 -0
  407. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/htest_wilcox_signed_r_results.json +0 -0
  408. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/ill_conditioned.csv +0 -0
  409. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/ill_conditioned_meta.json +0 -0
  410. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/ill_conditioned_r_results.json +0 -0
  411. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/large_coeffs.csv +0 -0
  412. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/large_coeffs_meta.json +0 -0
  413. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/large_coeffs_r_results.json +0 -0
  414. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_90_meta.json +0 -0
  415. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_90_r_results.json +0 -0
  416. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_normal_meta.json +0 -0
  417. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_normal_r_results.json +0 -0
  418. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_skewed_meta.json +0 -0
  419. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_ci_skewed_r_results.json +0 -0
  420. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_mean_balanced_meta.json +0 -0
  421. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_mean_balanced_r_results.json +0 -0
  422. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_mean_ordinary_meta.json +0 -0
  423. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_mean_ordinary_r_results.json +0 -0
  424. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_median_meta.json +0 -0
  425. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_median_r_results.json +0 -0
  426. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_variance_meta.json +0 -0
  427. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_boot_variance_r_results.json +0 -0
  428. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_greater_meta.json +0 -0
  429. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_greater_r_results.json +0 -0
  430. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_not_significant_meta.json +0 -0
  431. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_not_significant_r_results.json +0 -0
  432. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_significant_meta.json +0 -0
  433. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mc_perm_significant_r_results.json +0 -0
  434. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/glmm_binomial.csv +0 -0
  435. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/glmm_poisson.csv +0 -0
  436. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/lmm_crossed.csv +0 -0
  437. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/lmm_intercept.csv +0 -0
  438. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/lmm_ml.csv +0 -0
  439. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/lmm_no_effect.csv +0 -0
  440. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/lmm_slope.csv +0 -0
  441. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/mixed_meta.json +0 -0
  442. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/mixed/mixed_r_results.json +0 -0
  443. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/near_square.csv +0 -0
  444. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/near_square_meta.json +0 -0
  445. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/near_square_r_results.json +0 -0
  446. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/no_intercept.csv +0 -0
  447. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/no_intercept_meta.json +0 -0
  448. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/no_intercept_r_results.json +0 -0
  449. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_anova_validation.R +0 -0
  450. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_descriptive_validation.R +0 -0
  451. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_glm_validation.R +0 -0
  452. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_hypothesis_validation.R +0 -0
  453. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_mixed_validation.R +0 -0
  454. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_montecarlo_validation.R +0 -0
  455. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_survival_validation.R +0 -0
  456. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_r_validation.R +0 -0
  457. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/run_validation.sh +0 -0
  458. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/small_noise.csv +0 -0
  459. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/small_noise_meta.json +0 -0
  460. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/small_noise_r_results.json +0 -0
  461. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_breslow_meta.json +0 -0
  462. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_breslow_r_results.json +0 -0
  463. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_single_meta.json +0 -0
  464. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_single_r_results.json +0 -0
  465. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_ties_meta.json +0 -0
  466. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_ties_r_results.json +0 -0
  467. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_two_cov_meta.json +0 -0
  468. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_cox_two_cov_r_results.json +0 -0
  469. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_basic_meta.json +0 -0
  470. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_basic_r_results.json +0 -0
  471. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_heavy_cens_meta.json +0 -0
  472. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_heavy_cens_r_results.json +0 -0
  473. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_loglog_ci_meta.json +0 -0
  474. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_loglog_ci_r_results.json +0 -0
  475. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_no_cens_meta.json +0 -0
  476. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_no_cens_r_results.json +0 -0
  477. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_plain_ci_meta.json +0 -0
  478. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_plain_ci_r_results.json +0 -0
  479. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_ties_meta.json +0 -0
  480. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_km_ties_r_results.json +0 -0
  481. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_peto_meta.json +0 -0
  482. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_peto_r_results.json +0 -0
  483. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_three_group_meta.json +0 -0
  484. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_three_group_r_results.json +0 -0
  485. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_two_group_meta.json +0 -0
  486. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/surv_lr_two_group_r_results.json +0 -0
  487. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/tall_skinny.csv +0 -0
  488. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/tall_skinny_meta.json +0 -0
  489. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/tall_skinny_r_results.json +0 -0
  490. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/fixtures/validate_against_r.py +0 -0
  491. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/gam/__init__.py +0 -0
  492. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/gam/test_gam.py +0 -0
  493. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/__init__.py +0 -0
  494. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/conftest.py +0 -0
  495. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_chisq_test.py +0 -0
  496. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_design_split.py +0 -0
  497. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_fisher_test.py +0 -0
  498. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_gpu.py +0 -0
  499. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_ks_test.py +0 -0
  500. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_p_adjust.py +0 -0
  501. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_prop_test.py +0 -0
  502. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_r_validation.py +0 -0
  503. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_t_test.py +0 -0
  504. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_var_test.py +0 -0
  505. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/hypothesis/test_wilcox_test.py +0 -0
  506. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/__init__.py +0 -0
  507. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/references/generate_mice_fixtures.R +0 -0
  508. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/references/mice_reference.json +0 -0
  509. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/references/mice_validation_complete.csv +0 -0
  510. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/references/mice_validation_data.csv +0 -0
  511. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_datasets.py +0 -0
  512. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_design.py +0 -0
  513. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_pooling.py +0 -0
  514. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_r_validation.py +0 -0
  515. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_rng.py +0 -0
  516. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mice/test_visit.py +0 -0
  517. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/__init__.py +0 -0
  518. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/conftest.py +0 -0
  519. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_glmm.py +0 -0
  520. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_lmm_crossed.py +0 -0
  521. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_lmm_intercept.py +0 -0
  522. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_lmm_nested.py +0 -0
  523. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_lmm_slope.py +0 -0
  524. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_pls.py +0 -0
  525. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_r_validation.py +0 -0
  526. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_random_effects.py +0 -0
  527. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mixed/test_satterthwaite.py +0 -0
  528. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/__init__.py +0 -0
  529. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/conftest.py +0 -0
  530. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_batched_solver.py +0 -0
  531. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_boot_ci.py +0 -0
  532. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_bootstrap.py +0 -0
  533. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_gpu.py +0 -0
  534. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_influence.py +0 -0
  535. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_permutation.py +0 -0
  536. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/montecarlo/test_r_validation.py +0 -0
  537. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/multinomial/__init__.py +0 -0
  538. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/multinomial/test_multinom.py +0 -0
  539. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/multivariate/__init__.py +0 -0
  540. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/multivariate/test_multivariate.py +0 -0
  541. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/apple_em_reference.json +0 -0
  542. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/apple_reference.json +0 -0
  543. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/generate_em_fixtures.R +0 -0
  544. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_apple.json +0 -0
  545. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_complete.json +0 -0
  546. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_extreme.json +0 -0
  547. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_missvals.json +0 -0
  548. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_simple_mcar.json +0 -0
  549. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/little_mcar_summary.json +0 -0
  550. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/missvals_em_reference.json +0 -0
  551. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/missvals_reference.json +0 -0
  552. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/references/small_test_reference.json +0 -0
  553. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_em.py +0 -0
  554. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_gpu.py +0 -0
  555. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_mcar.py +0 -0
  556. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_mlest.py +0 -0
  557. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_monotone.py +0 -0
  558. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_no_silent_fallback.py +0 -0
  559. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/mvnmle/test_squarem.py +0 -0
  560. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/ordinal/__init__.py +0 -0
  561. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/ordinal/test_ordinal.py +0 -0
  562. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/benchmark.py +0 -0
  563. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/benchmark.r +0 -0
  564. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/conftest.py +0 -0
  565. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_fit.py +0 -0
  566. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_gamma_nb.py +0 -0
  567. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_glm.py +0 -0
  568. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_glm_gpu.py +0 -0
  569. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_glm_r_validation.py +0 -0
  570. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_module_split.py +0 -0
  571. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_r_validation.py +0 -0
  572. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_stress_gpu.py +0 -0
  573. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_terms.py +0 -0
  574. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/regression/test_terms_gpu.py +0 -0
  575. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/__init__.py +0 -0
  576. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/conftest.py +0 -0
  577. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_coxph.py +0 -0
  578. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_discrete_time.py +0 -0
  579. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_gpu.py +0 -0
  580. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_kaplan_meier.py +0 -0
  581. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_logrank.py +0 -0
  582. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/survival/test_r_validation.py +0 -0
  583. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/test_code_quality.py +0 -0
  584. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/timeseries/__init__.py +0 -0
  585. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/timeseries/test_acf_stationarity.py +0 -0
  586. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/timeseries/test_arima.py +0 -0
  587. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/timeseries/test_decomposition.py +0 -0
  588. {pystatistics-3.3.0 → pystatistics-3.4.1}/tests/timeseries/test_ets.py +0 -0
@@ -0,0 +1,23 @@
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
+ - CPU PMM (`mice` predictive mean matching) now scales to large datasets.
13
+ Replaced the dense `(n_mis, n_obs)` distance matrix in
14
+ `pystatistics/mice/methods/pmm.py:_match_donors` with a sorted-array windowed
15
+ k-NN (sort the observed predictions once, search a width-`2k` window around
16
+ each missing value's insertion point), matching R `mice`'s `matchindex`
17
+ approach. Cost drops from `O(n_mis·n_obs)` to `O(n_obs log n_obs + n_mis·k)`
18
+ in both time and memory. Measured CPU PMM (p=10-15, m=20, maxit=8): n=3000
19
+ 25.4s -> 0.65s (~39x); n=20000 went from minutes/hours to ~6.5s. The window is
20
+ provably exact (the global k nearest neighbours lie in `[pos-k, pos+k-1]` of
21
+ the sorted array), so the donor pool is unchanged; imputations remain
22
+ distributionally identical and still match R. Exact per-seed outputs differ
23
+ from 3.4.0 because the donor ordering within the k-NN set changed.
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.4.1
4
+
5
+ Performance: CPU predictive mean matching now scales to large datasets.
6
+
7
+ - The CPU PMM donor search no longer builds a dense distance matrix between
8
+ every missing and every observed value. It sorts the observed predictions
9
+ once and searches a small window around each missing value (the same approach
10
+ R's `mice` uses), reducing both time and memory from quadratic in the number
11
+ of rows to roughly `n log n`. In practice CPU PMM at n=3000 dropped from ~25s
12
+ to under 1s, and large problems (n=20000) that were effectively unusable now
13
+ finish in seconds.
14
+ - Results are unchanged statistically — the donor pool and all imputation
15
+ distributions are identical, and validation against R's `mice` still passes.
16
+ Exact per-seed imputed values can differ slightly from 3.4.0.
17
+
18
+ ## 3.4.0
19
+
20
+ GPU acceleration for MICE.
21
+
22
+ - **`mice(..., backend='gpu')` runs on CUDA GPUs.** The `m` imputation chains
23
+ run together on the GPU, with the per-variable linear solves and the
24
+ predictive-mean-matching donor search batched across chains. `backend='auto'`
25
+ uses a CUDA GPU when one is available and falls back to the CPU otherwise.
26
+ - **Large speedups on bigger problems.** Because the donor search dominates and
27
+ parallelises well, the GPU advantage grows with sample size — for example,
28
+ predictive mean matching was roughly 39× faster at n=1000 and 135× faster at
29
+ n=3000 than the CPU backend on an RTX 5070 Ti (m=20, maxit=8). GPU results
30
+ match the CPU backend at the standard GPU/FP32 tolerance.
31
+ - **`use_fp64=True`** runs the GPU path in double precision on CUDA for closer
32
+ agreement with the CPU reference (default is FP32, the fast path).
33
+ - GPU acceleration requires a CUDA GPU; Apple Silicon (MPS) is not yet supported
34
+ for MICE and is refused with a clear message rather than run unverified.
35
+
3
36
  ## 3.3.0
4
37
 
5
38
  Multiple imputation by chained equations (MICE) for multivariate missing data.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pystatistics
3
- Version: 3.3.0
3
+ Version: 3.4.1
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,7 +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
+ | `mice/` | Numeric | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice; CUDA GPU backend |
90
90
 
91
91
  See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed scope, GPU applicability, and implementation priority for each module.
92
92
 
@@ -413,6 +413,26 @@ pip install pystatistics[dev]
413
413
 
414
414
  ## What's New
415
415
 
416
+ ### 3.4.1 — Faster CPU predictive mean matching
417
+
418
+ - CPU PMM in `mice` now scales to large datasets: the donor search sorts the
419
+ observed predictions and scans a small window per missing value (as R's
420
+ `mice` does) instead of forming a full distance matrix, cutting time and
421
+ memory from quadratic to roughly `n log n`. Large problems that were
422
+ effectively unusable on the CPU now finish in seconds. Results are
423
+ statistically unchanged.
424
+
425
+ ### 3.4.0 — GPU acceleration for MICE
426
+
427
+ - `mice(..., backend='gpu')` runs the imputation chains on a CUDA GPU, batching
428
+ the per-variable solves and the predictive-mean-matching donor search across
429
+ chains. `backend='auto'` uses a CUDA GPU when available, else the CPU.
430
+ - The speedup grows with sample size (the donor search dominates and batches
431
+ well): predictive mean matching ran ~39× faster at n=1000 and ~135× faster at
432
+ n=3000 than the CPU backend on an RTX 5070 Ti. GPU results match the CPU
433
+ backend at the GPU/FP32 tolerance; pass `use_fp64=True` for double precision.
434
+ - Requires a CUDA GPU; Apple Silicon (MPS) is not yet supported for MICE.
435
+
416
436
  ### 3.3.0 — Multiple imputation (MICE)
417
437
 
418
438
  - New `mice` module: multiple imputation by chained equations for numeric data
@@ -39,7 +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
+ | `mice/` | Numeric | Multiple imputation by chained equations: PMM and Bayesian linear regression, Rubin's-rules pooling, validated against R mice; CUDA GPU backend |
43
43
 
44
44
  See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed scope, GPU applicability, and implementation priority for each module.
45
45
 
@@ -366,6 +366,26 @@ pip install pystatistics[dev]
366
366
 
367
367
  ## What's New
368
368
 
369
+ ### 3.4.1 — Faster CPU predictive mean matching
370
+
371
+ - CPU PMM in `mice` now scales to large datasets: the donor search sorts the
372
+ observed predictions and scans a small window per missing value (as R's
373
+ `mice` does) instead of forming a full distance matrix, cutting time and
374
+ memory from quadratic to roughly `n log n`. Large problems that were
375
+ effectively unusable on the CPU now finish in seconds. Results are
376
+ statistically unchanged.
377
+
378
+ ### 3.4.0 — GPU acceleration for MICE
379
+
380
+ - `mice(..., backend='gpu')` runs the imputation chains on a CUDA GPU, batching
381
+ the per-variable solves and the predictive-mean-matching donor search across
382
+ chains. `backend='auto'` uses a CUDA GPU when available, else the CPU.
383
+ - The speedup grows with sample size (the donor search dominates and batches
384
+ well): predictive mean matching ran ~39× faster at n=1000 and ~135× faster at
385
+ n=3000 than the CPU backend on an RTX 5070 Ti. GPU results match the CPU
386
+ backend at the GPU/FP32 tolerance; pass `use_fp64=True` for double precision.
387
+ - Requires a CUDA GPU; Apple Silicon (MPS) is not yet supported for MICE.
388
+
369
389
  ### 3.3.0 — Multiple imputation (MICE)
370
390
 
371
391
  - New `mice` module: multiple imputation by chained equations for numeric data
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "pystatistics"
7
- version = "3.3.0"
7
+ version = "3.4.1"
8
8
  description = "GPU-accelerated statistical computing for Python"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -16,7 +16,7 @@ Usage:
16
16
  result = fit(design)
17
17
  """
18
18
 
19
- __version__ = "3.3.0"
19
+ __version__ = "3.4.1"
20
20
  __author__ = "Hai-Shuo"
21
21
  __email__ = "contact@sgcx.org"
22
22
 
@@ -0,0 +1,138 @@
1
+ """
2
+ Batched Bayesian linear-regression posterior draw on the GPU.
3
+
4
+ This is the GPU counterpart of ``methods/_linreg.py``: the same Bayesian draw,
5
+ but vectorized over the ``m`` imputation chains as the leading batch dimension.
6
+ At a given sweep step every chain is fitting the *same* target column on the
7
+ *same* observed rows, but with different predictor values (each chain imputed
8
+ the other columns differently), so we solve ``m`` independent linear systems at
9
+ once with batched cuBLAS/cuSOLVER kernels.
10
+
11
+ Posterior draw (identical model to the CPU path):
12
+
13
+ beta_hat = (X'X + ridge)^{-1} X'y batched solve
14
+ df = max(n_obs - n_params, 1) integer, shared by chains
15
+ sigma* = sqrt( RSS / chi2(df) ) chi2 = sum of df squared N(0,1)
16
+ beta* = beta_hat + sigma* * L z L L' = (X'X + ridge)^{-1}
17
+
18
+ The chi-square is built from standard normals (``df`` is a non-negative integer)
19
+ so the only randomness source is the seeded ``torch.Generator`` — no reliance on
20
+ ``torch.distributions``, which ignores explicit generators.
21
+
22
+ All randomness flows through the passed generator (CLAUDE.md Rule 6). Results
23
+ match the CPU reference distributionally, at the GPU/FP32 tolerance tier — not
24
+ bit-for-bit (different RNG, single precision).
25
+ """
26
+
27
+ from __future__ import annotations
28
+
29
+ from dataclasses import dataclass
30
+
31
+ # Matches the CPU ridge (methods/_linreg.py) — a tiny relative penalty keeping
32
+ # the batched Gram matrices invertible under FP32.
33
+ _DEFAULT_RIDGE = 1e-5
34
+
35
+
36
+ @dataclass
37
+ class BatchedLinRegDraw:
38
+ """Batched point estimate + posterior draw (leading dim = m chains)."""
39
+
40
+ beta_hat: "object" # (m, q+1) tensor
41
+ beta_draw: "object" # (m, q+1) tensor
42
+ sigma_draw: "object" # (m,) tensor
43
+
44
+
45
+ def add_intercept(X):
46
+ """Prepend a ones column to a batched predictor tensor (m, n, q) -> (m,n,q+1)."""
47
+ import torch
48
+
49
+ m, n, _ = X.shape
50
+ ones = torch.ones((m, n, 1), dtype=X.dtype, device=X.device)
51
+ return torch.cat([ones, X], dim=2)
52
+
53
+
54
+ def batched_bayes_linreg_draw(
55
+ y_obs,
56
+ X_obs,
57
+ gen,
58
+ ridge: float = _DEFAULT_RIDGE,
59
+ ) -> BatchedLinRegDraw:
60
+ """Draw once from the Gaussian linear-model posterior for every chain.
61
+
62
+ Parameters
63
+ ----------
64
+ y_obs : (m, n_obs) tensor
65
+ Observed responses (identical across chains, batched for uniform ops).
66
+ X_obs : (m, n_obs, q) tensor
67
+ Observed predictors WITHOUT an intercept column (added internally).
68
+ gen : torch.Generator
69
+ Sole randomness source, on the same device as the tensors.
70
+ ridge : float
71
+ Relative ridge penalty on the diagonal of X'X.
72
+ """
73
+ import torch
74
+
75
+ Xa = add_intercept(X_obs) # (m, n_obs, q+1)
76
+ m, n_obs, n_params = Xa.shape
77
+ dtype, device = Xa.dtype, Xa.device
78
+
79
+ Xt = Xa.transpose(1, 2) # (m, q+1, n_obs)
80
+ XtX = Xt @ Xa # (m, q+1, q+1)
81
+
82
+ diag = torch.diagonal(XtX, dim1=1, dim2=2) # (m, q+1)
83
+ diag_mean = diag.mean(dim=1).clamp_min(torch.finfo(dtype).tiny) # (m,)
84
+ eye = torch.eye(n_params, dtype=dtype, device=device)
85
+ XtX_ridge = XtX + ridge * diag_mean[:, None, None] * eye
86
+
87
+ Xty = Xt @ y_obs.unsqueeze(-1) # (m, q+1, 1)
88
+ beta_hat = torch.linalg.solve(XtX_ridge, Xty).squeeze(-1) # (m, q+1)
89
+
90
+ resid = y_obs - (Xa @ beta_hat.unsqueeze(-1)).squeeze(-1) # (m, n_obs)
91
+ rss = (resid * resid).sum(dim=1) # (m,)
92
+ df = max(n_obs - n_params, 1)
93
+
94
+ # chi2(df) = sum of df squared standard normals (df is an integer).
95
+ z_chi = torch.randn((m, df), generator=gen, dtype=dtype, device=device)
96
+ chi = (z_chi * z_chi).sum(dim=1).clamp_min(torch.finfo(dtype).tiny) # (m,)
97
+ sigma_draw = torch.where(
98
+ rss > 0, torch.sqrt(rss / chi), torch.zeros_like(rss)
99
+ ) # (m,)
100
+
101
+ V = torch.linalg.inv(XtX_ridge) # (m, q+1, q+1)
102
+ L = _batched_safe_cholesky(V) # (m, q+1, q+1), L L' = V
103
+ z_beta = torch.randn((m, n_params), generator=gen, dtype=dtype, device=device)
104
+ beta_draw = beta_hat + sigma_draw[:, None] * (L @ z_beta.unsqueeze(-1)).squeeze(-1)
105
+
106
+ return BatchedLinRegDraw(
107
+ beta_hat=beta_hat, beta_draw=beta_draw, sigma_draw=sigma_draw
108
+ )
109
+
110
+
111
+ def _batched_safe_cholesky(V):
112
+ """Lower Cholesky of each (symmetric PSD) matrix in a batch, with jitter.
113
+
114
+ ``V`` is a batch of inverse-Gram matrices — positive definite in exact
115
+ arithmetic, but FP32 rounding can leave one marginally indefinite. We
116
+ symmetrize and add escalating jitter to the *whole batch* (cheap, keeps the
117
+ op batched) until ``cholesky_ex`` reports success for every matrix.
118
+ """
119
+ import torch
120
+
121
+ Vs = 0.5 * (V + V.transpose(1, 2))
122
+ eye = torch.eye(Vs.shape[1], dtype=Vs.dtype, device=Vs.device)
123
+ diag = torch.diagonal(Vs, dim1=1, dim2=2)
124
+ scale = diag.mean().clamp_min(1.0).item()
125
+
126
+ jitter = 0.0
127
+ for _ in range(8):
128
+ M = Vs if jitter == 0.0 else Vs + jitter * eye
129
+ L, info = torch.linalg.cholesky_ex(M)
130
+ if not torch.any(info):
131
+ return L
132
+ jitter = scale * (1e-8 if jitter == 0.0 else 10.0 * jitter)
133
+
134
+ # Documented last resort (Rule 1): eigenvalue-clipped PSD factor. Reached
135
+ # only if a matrix is badly degenerate despite ridge + jitter.
136
+ w, Q = torch.linalg.eigh(Vs)
137
+ w = w.clamp_min(0.0)
138
+ return Q @ torch.diag_embed(torch.sqrt(w))
@@ -0,0 +1,81 @@
1
+ """
2
+ Batched GPU imputation methods: ``norm`` and ``pmm``.
3
+
4
+ These mirror ``methods/norm.py`` and ``methods/pmm.py`` but operate on tensors
5
+ batched over the ``m`` chains. Each takes the observed/missing predictor blocks
6
+ for one target column across all chains and returns the imputed values for every
7
+ chain at once, so a whole sweep step is a handful of batched kernels.
8
+
9
+ The GPU backend dispatches to these by method name; a name with no GPU
10
+ implementation is refused by the backend (fail loud, Rule 1) rather than
11
+ silently downgraded.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from pystatistics.mice.backends._gpu_linreg import (
17
+ add_intercept,
18
+ batched_bayes_linreg_draw,
19
+ )
20
+
21
+
22
+ def gpu_norm_impute(y_obs, X_obs, X_mis, gen, *, donors=None):
23
+ """Batched Bayesian linear-regression imputation (R ``norm``).
24
+
25
+ Parameters mirror the CPU method but are batched: ``y_obs`` (m, n_obs),
26
+ ``X_obs`` (m, n_obs, q), ``X_mis`` (m, n_mis, q). Returns (m, n_mis).
27
+ ``donors`` is accepted and ignored so the backend can call every method
28
+ with one uniform signature.
29
+ """
30
+ import torch
31
+
32
+ draw = batched_bayes_linreg_draw(y_obs, X_obs, gen)
33
+ Xa_mis = add_intercept(X_mis)
34
+ yhat_mis = (Xa_mis @ draw.beta_draw.unsqueeze(-1)).squeeze(-1) # (m, n_mis)
35
+ noise = torch.randn(
36
+ yhat_mis.shape, generator=gen, dtype=yhat_mis.dtype, device=yhat_mis.device
37
+ )
38
+ return yhat_mis + draw.sigma_draw[:, None] * noise
39
+
40
+
41
+ def gpu_pmm_impute(y_obs, X_obs, X_mis, gen, *, donors=5):
42
+ """Batched predictive mean matching (R ``pmm``, matchtype=1).
43
+
44
+ Observed fitted values use ``beta_hat``; missing fitted values use the
45
+ posterior draw ``beta*``. For each missing row in each chain, pick one of
46
+ the ``k`` nearest observed fitted values at random and copy that observed
47
+ value. Returns (m, n_mis).
48
+ """
49
+ import torch
50
+
51
+ draw = batched_bayes_linreg_draw(y_obs, X_obs, gen)
52
+ Xa_obs = add_intercept(X_obs)
53
+ Xa_mis = add_intercept(X_mis)
54
+ yhat_obs = (Xa_obs @ draw.beta_hat.unsqueeze(-1)).squeeze(-1) # (m, n_obs)
55
+ yhat_mis = (Xa_mis @ draw.beta_draw.unsqueeze(-1)).squeeze(-1) # (m, n_mis)
56
+
57
+ m, n_obs = yhat_obs.shape
58
+ n_mis = yhat_mis.shape[1]
59
+ k = min(donors, n_obs)
60
+
61
+ # |yhat_mis - yhat_obs| for every (chain, missing row, observed row).
62
+ dist = (yhat_mis[:, :, None] - yhat_obs[:, None, :]).abs() # (m, n_mis, n_obs)
63
+ # k nearest observed fitted values (indices into n_obs).
64
+ _, cand = torch.topk(dist, k, dim=2, largest=False) # (m, n_mis, k)
65
+
66
+ # One random donor per (chain, missing row) among its k candidates.
67
+ pick = torch.randint(
68
+ 0, k, (m, n_mis), generator=gen, device=yhat_obs.device
69
+ ) # (m, n_mis)
70
+ donor_idx = torch.gather(cand, 2, pick.unsqueeze(-1)).squeeze(-1) # (m, n_mis)
71
+
72
+ # Copy the observed donor values (gather along the observed-row axis).
73
+ return torch.gather(y_obs, 1, donor_idx) # (m, n_mis)
74
+
75
+
76
+ # Method-name -> batched implementation. The backend translates the design's
77
+ # per-column method name through this table; unknown names are refused there.
78
+ GPU_METHODS = {
79
+ "norm": gpu_norm_impute,
80
+ "pmm": gpu_pmm_impute,
81
+ }
@@ -17,6 +17,7 @@ import numpy as np
17
17
  from pystatistics.core.compute.timing import Timer
18
18
  from pystatistics.core.result import Result
19
19
  from pystatistics.mice._chain import run_chain
20
+ from pystatistics.mice._rng import spawn_streams
20
21
  from pystatistics.mice.design import MICEDesign
21
22
  from pystatistics.mice.solution import MICEParams
22
23
 
@@ -35,7 +36,7 @@ class CPUMiceBackend:
35
36
  m: int,
36
37
  maxit: int,
37
38
  visit_sequence: tuple[int, ...],
38
- streams: list[np.random.Generator],
39
+ seed: int,
39
40
  ) -> Result[MICEParams]:
40
41
  """Run ``m`` chains and package the imputations.
41
42
 
@@ -48,13 +49,15 @@ class CPUMiceBackend:
48
49
  Iterations per chain.
49
50
  visit_sequence : tuple of int
50
51
  Column visit order within each iteration.
51
- streams : list of numpy.random.Generator
52
- One independent RNG per chain; ``len(streams) == m`` (the solver
53
- guarantees this).
52
+ seed : int
53
+ Master RNG seed. The backend spawns one independent, reproducible
54
+ stream per chain from it.
54
55
  """
55
56
  timer = Timer()
56
57
  timer.start()
57
58
 
59
+ streams = spawn_streams(seed, m)
60
+
58
61
  completed = np.empty((m, design.n, design.p), dtype=np.float64)
59
62
  chain_means = np.empty((m, maxit, len(design.incomplete_columns)))
60
63
  chain_vars = np.empty((m, maxit, len(design.incomplete_columns)))
@@ -0,0 +1,170 @@
1
+ """
2
+ GPU backend for MICE.
3
+
4
+ Implements the same ``run`` entrypoint as the CPU backend, but runs all ``m``
5
+ imputation chains concurrently on a CUDA GPU with the chain index as the leading
6
+ tensor batch dimension. Each sweep step — visit column ``j``, fit its method on
7
+ the observed rows, overwrite its missing cells — becomes a handful of batched
8
+ kernels across the ``m`` chains (batched linear solves + Cholesky, and for PMM a
9
+ batched nearest-neighbour donor search).
10
+
11
+ Why batch over chains: the ``m`` chains are statistically independent and share
12
+ the missingness pattern, so they have identical shapes at every step — an ideal
13
+ batch. The sweep stays sequential *within* a chain (column ``j`` depends on the
14
+ columns imputed before it), which is inherent to chained equations.
15
+
16
+ Validation tier: GPU results match the CPU reference distributionally at the
17
+ ``GPU_FP32`` tolerance, not bit-for-bit (FP32 + a different RNG). FP64 is
18
+ available on CUDA (``use_fp64=True``) for closer parity.
19
+
20
+ Determinism: a single seeded ``torch.Generator`` on the device is the only
21
+ randomness source. Given the same seed and device, a run reproduces its own
22
+ output to within FP32 kernel non-determinism.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ from pystatistics.core.compute.timing import Timer
28
+ from pystatistics.core.compute.torch_interop import to_host_f64
29
+ from pystatistics.core.exceptions import ValidationError
30
+ from pystatistics.core.result import Result
31
+ from pystatistics.mice.backends._gpu_methods import GPU_METHODS
32
+ from pystatistics.mice.design import MICEDesign
33
+ from pystatistics.mice.solution import MICEParams
34
+
35
+ # R mice default donor count for PMM (the design does not carry a per-column
36
+ # donor count, so the GPU path uses the same default as the CPU PMMMethod).
37
+ _PMM_DONORS = 5
38
+
39
+
40
+ class GPUMiceBackend:
41
+ """Runs MICE chains batched on a CUDA GPU."""
42
+
43
+ def __init__(self, device: str = "cuda", use_fp64: bool = False):
44
+ self.device = device
45
+ self.use_fp64 = use_fp64
46
+
47
+ @property
48
+ def name(self) -> str:
49
+ return f"gpu_{'fp64' if self.use_fp64 else 'fp32'}"
50
+
51
+ def run(
52
+ self,
53
+ design: MICEDesign,
54
+ *,
55
+ m: int,
56
+ maxit: int,
57
+ visit_sequence: tuple[int, ...],
58
+ seed: int,
59
+ ) -> Result[MICEParams]:
60
+ import torch
61
+
62
+ # Validate that every incomplete column's method has a GPU kernel before
63
+ # touching the device (fail loud at the boundary, Rule 2).
64
+ for j in design.incomplete_columns:
65
+ meth = design.method_for(j)
66
+ if meth not in GPU_METHODS:
67
+ raise ValidationError(
68
+ f"Method {meth!r} (column {j}) has no GPU implementation. "
69
+ f"GPU methods: {sorted(GPU_METHODS)}. Use backend='cpu'."
70
+ )
71
+
72
+ timer = Timer()
73
+ timer.start()
74
+
75
+ dtype = torch.float64 if self.use_fp64 else torch.float32
76
+ dev = torch.device(self.device)
77
+ gen = torch.Generator(device=dev)
78
+ gen.manual_seed(int(seed))
79
+
80
+ n, p = design.n, design.p
81
+ incomplete = design.incomplete_columns
82
+ incomplete_pos = {j: k for k, j in enumerate(incomplete)}
83
+
84
+ with timer.section("transfer"):
85
+ base = torch.as_tensor(design.data, device=dev, dtype=dtype) # (n, p)
86
+ mask = torch.as_tensor(design.missing_mask, device=dev) # (n, p)
87
+ # m independent copies of the data (chains diverge after init).
88
+ data = base.unsqueeze(0).repeat(m, 1, 1) # (m, n, p)
89
+
90
+ # Precompute per-incomplete-column index tensors (shared by all chains).
91
+ obs_idx, mis_idx, pred_idx = {}, {}, {}
92
+ for j in incomplete:
93
+ mcol = mask[:, j]
94
+ obs_idx[j] = torch.nonzero(~mcol, as_tuple=False).squeeze(1)
95
+ mis_idx[j] = torch.nonzero(mcol, as_tuple=False).squeeze(1)
96
+ pred_idx[j] = torch.tensor(
97
+ [c for c in range(p) if c != j], device=dev, dtype=torch.long
98
+ )
99
+
100
+ with timer.section("init"):
101
+ self._initialise(data, base, obs_idx, mis_idx, incomplete, m, gen, dev)
102
+
103
+ chain_mean = torch.empty((m, maxit, len(incomplete)), dtype=dtype, device=dev)
104
+ chain_var = torch.empty((m, maxit, len(incomplete)), dtype=dtype, device=dev)
105
+
106
+ with timer.section("sweep"):
107
+ for it in range(maxit):
108
+ for j in visit_sequence:
109
+ method_fn = GPU_METHODS[design.method_for(j)]
110
+ X = data[:, :, pred_idx[j]] # (m, n, q)
111
+ X_obs = X[:, obs_idx[j], :] # (m, n_obs, q)
112
+ X_mis = X[:, mis_idx[j], :] # (m, n_mis, q)
113
+ y_obs = data[:, obs_idx[j], j] # (m, n_obs)
114
+
115
+ imputed = method_fn(
116
+ y_obs, X_obs, X_mis, gen, donors=_PMM_DONORS
117
+ )
118
+ data[:, mis_idx[j], j] = imputed
119
+
120
+ for j in incomplete:
121
+ cells = data[:, mis_idx[j], j] # (m, n_mis)
122
+ k = incomplete_pos[j]
123
+ chain_mean[:, it, k] = cells.mean(dim=1)
124
+ chain_var[:, it, k] = cells.var(dim=1, unbiased=False)
125
+
126
+ with timer.section("download"):
127
+ completed = to_host_f64(data)
128
+ chain_mean_host = to_host_f64(chain_mean)
129
+ chain_var_host = to_host_f64(chain_var)
130
+
131
+ timer.stop()
132
+
133
+ params = MICEParams(
134
+ completed=completed,
135
+ chain_mean=chain_mean_host,
136
+ chain_var=chain_var_host,
137
+ incomplete_columns=incomplete,
138
+ m=m,
139
+ maxit=maxit,
140
+ visit_sequence=visit_sequence,
141
+ )
142
+ return Result(
143
+ params=params,
144
+ info={
145
+ "method": "chained_equations",
146
+ "m": m,
147
+ "maxit": maxit,
148
+ "device": self.device,
149
+ "precision": "fp64" if self.use_fp64 else "fp32",
150
+ "visit_sequence": list(visit_sequence),
151
+ },
152
+ timing=timer.result(),
153
+ backend_name=self.name,
154
+ warnings=(),
155
+ )
156
+
157
+ @staticmethod
158
+ def _initialise(data, base, obs_idx, mis_idx, incomplete, m, gen, dev):
159
+ """Fill missing cells by sampling observed values of the same column,
160
+ independently per chain. Mutates ``data`` in place."""
161
+ import torch
162
+
163
+ for j in incomplete:
164
+ observed = base[obs_idx[j], j] # (n_obs,)
165
+ n_obs = observed.shape[0]
166
+ n_mis = mis_idx[j].shape[0]
167
+ draw_idx = torch.randint(
168
+ 0, n_obs, (m, n_mis), generator=gen, device=dev
169
+ )
170
+ data[:, mis_idx[j], j] = observed[draw_idx]
@@ -63,24 +63,45 @@ def _match_donors(
63
63
  """For each missing fitted value, pick one of its ``k`` nearest observed
64
64
  fitted values at random; return the chosen observed-row indices.
65
65
 
66
- Vectorized across all missing rows this is the donor-search kernel a
67
- Stage-2 GPU backend would replace with a batched nearest-neighbour search.
66
+ Scales like R's ``mice`` matcher: sort the observed fitted values once, then
67
+ for each missing value search a small window around its insertion point
68
+ instead of forming the full ``(n_mis, n_obs)`` distance matrix. Cost is
69
+ ``O(n_obs log n_obs + n_mis·k)`` time and ``O(n_mis·k)`` memory — the dense
70
+ version was ``O(n_mis·n_obs)`` in both, which blows up on large data.
71
+
72
+ The window is provably exact. In a sorted array the ``k`` nearest neighbours
73
+ of a query lie in the contiguous block ``[pos-k, pos+k-1]`` around the
74
+ insertion point ``pos``; a width-``2k`` window covers that block (shifted to
75
+ stay in range near the ends), so the windowed k-NN equals the global k-NN.
68
76
  """
69
77
  n_obs = yhat_obs.shape[0]
78
+ n_mis = yhat_mis.shape[0]
70
79
  k = min(donors, n_obs)
71
80
 
72
- # |yhat_mis_i - yhat_obs_j| for every (i, j): (n_mis, n_obs).
73
- dist = np.abs(yhat_mis[:, None] - yhat_obs[None, :])
81
+ # Sort donor predictions once; keep the map back to original obs rows.
82
+ order = np.argsort(yhat_obs, kind="stable")
83
+ sorted_obs = yhat_obs[order]
74
84
 
75
- # Indices of the k smallest distances per row (unordered within the k).
76
- if k < n_obs:
77
- cand = np.argpartition(dist, k - 1, axis=1)[:, :k]
85
+ # Insertion point of each missing prediction into the sorted donors.
86
+ pos = np.searchsorted(sorted_obs, yhat_mis)
87
+
88
+ # Window of distinct candidate donors guaranteed to contain the k nearest.
89
+ w = min(2 * k, n_obs)
90
+ start = np.clip(pos - k, 0, n_obs - w) # (n_mis,)
91
+ win = start[:, None] + np.arange(w)[None, :] # (n_mis, w) sorted-idx
92
+ dist = np.abs(sorted_obs[win] - yhat_mis[:, None]) # (n_mis, w)
93
+
94
+ # k smallest distances within the window (unordered within the k).
95
+ if k < w:
96
+ knn = np.argpartition(dist, k - 1, axis=1)[:, :k] # (n_mis, k) window cols
78
97
  else:
79
- cand = np.broadcast_to(np.arange(n_obs), (yhat_mis.shape[0], n_obs))
98
+ knn = np.broadcast_to(np.arange(w), (n_mis, w))
80
99
 
81
- # One random donor per row among its k candidates.
82
- pick = rng.integers(0, k, size=yhat_mis.shape[0])
83
- return cand[np.arange(yhat_mis.shape[0]), pick]
100
+ rows = np.arange(n_mis)
101
+ pick = rng.integers(0, k, size=n_mis) # one donor per row
102
+ chosen_win_col = knn[rows, pick] # (n_mis,)
103
+ chosen_sorted = win[rows, chosen_win_col] # idx into sorted_obs
104
+ return order[chosen_sorted] # back to original rows
84
105
 
85
106
 
86
107
  register(PMMMethod())