pystatistics 1.0.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.
Files changed (448) hide show
  1. pystatistics-1.0.0/.github/workflows/publish.yml +45 -0
  2. pystatistics-1.0.0/.gitignore +116 -0
  3. pystatistics-1.0.0/LICENSE +21 -0
  4. pystatistics-1.0.0/PKG-INFO +327 -0
  5. pystatistics-1.0.0/README.md +281 -0
  6. pystatistics-1.0.0/docs/DESIGN.md +1669 -0
  7. pystatistics-1.0.0/docs/Forge.md +291 -0
  8. pystatistics-1.0.0/docs/Makefile +14 -0
  9. pystatistics-1.0.0/docs/PYSTATSBIO_CONTEXT.md +785 -0
  10. pystatistics-1.0.0/docs/ROADMAP.md +177 -0
  11. pystatistics-1.0.0/docs/_static/custom.css +5 -0
  12. pystatistics-1.0.0/docs/anova.rst +9 -0
  13. pystatistics-1.0.0/docs/conf.py +61 -0
  14. pystatistics-1.0.0/docs/core.rst +16 -0
  15. pystatistics-1.0.0/docs/descriptive.rst +9 -0
  16. pystatistics-1.0.0/docs/hypothesis.rst +9 -0
  17. pystatistics-1.0.0/docs/index.rst +25 -0
  18. pystatistics-1.0.0/docs/mixed.rst +9 -0
  19. pystatistics-1.0.0/docs/montecarlo.rst +9 -0
  20. pystatistics-1.0.0/docs/mvnmle.rst +9 -0
  21. pystatistics-1.0.0/docs/regression.rst +9 -0
  22. pystatistics-1.0.0/docs/survival.rst +9 -0
  23. pystatistics-1.0.0/pyproject.toml +94 -0
  24. pystatistics-1.0.0/pystatistics/__init__.py +44 -0
  25. pystatistics-1.0.0/pystatistics/anova/__init__.py +36 -0
  26. pystatistics-1.0.0/pystatistics/anova/_common.py +119 -0
  27. pystatistics-1.0.0/pystatistics/anova/_contrasts.py +248 -0
  28. pystatistics-1.0.0/pystatistics/anova/_levene.py +87 -0
  29. pystatistics-1.0.0/pystatistics/anova/_posthoc.py +291 -0
  30. pystatistics-1.0.0/pystatistics/anova/_repeated.py +395 -0
  31. pystatistics-1.0.0/pystatistics/anova/_ss.py +307 -0
  32. pystatistics-1.0.0/pystatistics/anova/design.py +214 -0
  33. pystatistics-1.0.0/pystatistics/anova/solution.py +397 -0
  34. pystatistics-1.0.0/pystatistics/anova/solvers.py +478 -0
  35. pystatistics-1.0.0/pystatistics/core/__init__.py +41 -0
  36. pystatistics-1.0.0/pystatistics/core/capabilities.py +49 -0
  37. pystatistics-1.0.0/pystatistics/core/compute/__init__.py +34 -0
  38. pystatistics-1.0.0/pystatistics/core/compute/device.py +142 -0
  39. pystatistics-1.0.0/pystatistics/core/compute/linalg/__init__.py +15 -0
  40. pystatistics-1.0.0/pystatistics/core/compute/linalg/batched.py +153 -0
  41. pystatistics-1.0.0/pystatistics/core/compute/linalg/cholesky.py +7 -0
  42. pystatistics-1.0.0/pystatistics/core/compute/linalg/determinant.py +7 -0
  43. pystatistics-1.0.0/pystatistics/core/compute/linalg/qr.py +101 -0
  44. pystatistics-1.0.0/pystatistics/core/compute/linalg/solve.py +7 -0
  45. pystatistics-1.0.0/pystatistics/core/compute/linalg/svd.py +7 -0
  46. pystatistics-1.0.0/pystatistics/core/compute/optimization/__init__.py +9 -0
  47. pystatistics-1.0.0/pystatistics/core/compute/optimization/convergence.py +7 -0
  48. pystatistics-1.0.0/pystatistics/core/compute/precision.py +115 -0
  49. pystatistics-1.0.0/pystatistics/core/compute/timing.py +135 -0
  50. pystatistics-1.0.0/pystatistics/core/compute/tolerances.py +88 -0
  51. pystatistics-1.0.0/pystatistics/core/datasource.py +276 -0
  52. pystatistics-1.0.0/pystatistics/core/exceptions.py +126 -0
  53. pystatistics-1.0.0/pystatistics/core/protocols.py +122 -0
  54. pystatistics-1.0.0/pystatistics/core/result.py +86 -0
  55. pystatistics-1.0.0/pystatistics/core/validation.py +224 -0
  56. pystatistics-1.0.0/pystatistics/descriptive/__init__.py +37 -0
  57. pystatistics-1.0.0/pystatistics/descriptive/_missing.py +100 -0
  58. pystatistics-1.0.0/pystatistics/descriptive/_quantile_types.py +137 -0
  59. pystatistics-1.0.0/pystatistics/descriptive/backends/__init__.py +5 -0
  60. pystatistics-1.0.0/pystatistics/descriptive/backends/cpu.py +576 -0
  61. pystatistics-1.0.0/pystatistics/descriptive/backends/gpu.py +357 -0
  62. pystatistics-1.0.0/pystatistics/descriptive/design.py +166 -0
  63. pystatistics-1.0.0/pystatistics/descriptive/solution.py +260 -0
  64. pystatistics-1.0.0/pystatistics/descriptive/solvers.py +316 -0
  65. pystatistics-1.0.0/pystatistics/hypothesis/__init__.py +39 -0
  66. pystatistics-1.0.0/pystatistics/hypothesis/_common.py +66 -0
  67. pystatistics-1.0.0/pystatistics/hypothesis/_p_adjust.py +264 -0
  68. pystatistics-1.0.0/pystatistics/hypothesis/backends/__init__.py +1 -0
  69. pystatistics-1.0.0/pystatistics/hypothesis/backends/_chisq_test.py +228 -0
  70. pystatistics-1.0.0/pystatistics/hypothesis/backends/_fisher_test.py +373 -0
  71. pystatistics-1.0.0/pystatistics/hypothesis/backends/_ks_test.py +159 -0
  72. pystatistics-1.0.0/pystatistics/hypothesis/backends/_prop_test.py +300 -0
  73. pystatistics-1.0.0/pystatistics/hypothesis/backends/_t_test.py +193 -0
  74. pystatistics-1.0.0/pystatistics/hypothesis/backends/_var_test.py +83 -0
  75. pystatistics-1.0.0/pystatistics/hypothesis/backends/_wilcox_test.py +358 -0
  76. pystatistics-1.0.0/pystatistics/hypothesis/backends/cpu.py +78 -0
  77. pystatistics-1.0.0/pystatistics/hypothesis/backends/gpu.py +401 -0
  78. pystatistics-1.0.0/pystatistics/hypothesis/design.py +727 -0
  79. pystatistics-1.0.0/pystatistics/hypothesis/solution.py +238 -0
  80. pystatistics-1.0.0/pystatistics/hypothesis/solvers.py +435 -0
  81. pystatistics-1.0.0/pystatistics/mixed/__init__.py +19 -0
  82. pystatistics-1.0.0/pystatistics/mixed/_common.py +126 -0
  83. pystatistics-1.0.0/pystatistics/mixed/_deviance.py +125 -0
  84. pystatistics-1.0.0/pystatistics/mixed/_pirls.py +122 -0
  85. pystatistics-1.0.0/pystatistics/mixed/_pls.py +194 -0
  86. pystatistics-1.0.0/pystatistics/mixed/_random_effects.py +294 -0
  87. pystatistics-1.0.0/pystatistics/mixed/_satterthwaite.py +291 -0
  88. pystatistics-1.0.0/pystatistics/mixed/design.py +127 -0
  89. pystatistics-1.0.0/pystatistics/mixed/solution.py +462 -0
  90. pystatistics-1.0.0/pystatistics/mixed/solvers.py +609 -0
  91. pystatistics-1.0.0/pystatistics/montecarlo/__init__.py +24 -0
  92. pystatistics-1.0.0/pystatistics/montecarlo/_ci.py +262 -0
  93. pystatistics-1.0.0/pystatistics/montecarlo/_common.py +51 -0
  94. pystatistics-1.0.0/pystatistics/montecarlo/_influence.py +91 -0
  95. pystatistics-1.0.0/pystatistics/montecarlo/backends/__init__.py +0 -0
  96. pystatistics-1.0.0/pystatistics/montecarlo/backends/cpu.py +303 -0
  97. pystatistics-1.0.0/pystatistics/montecarlo/backends/gpu.py +126 -0
  98. pystatistics-1.0.0/pystatistics/montecarlo/design.py +205 -0
  99. pystatistics-1.0.0/pystatistics/montecarlo/solution.py +246 -0
  100. pystatistics-1.0.0/pystatistics/montecarlo/solvers.py +261 -0
  101. pystatistics-1.0.0/pystatistics/mvnmle/__init__.py +32 -0
  102. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/__init__.py +31 -0
  103. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/base.py +267 -0
  104. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/cpu.py +313 -0
  105. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/gpu_fp32.py +329 -0
  106. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/gpu_fp64.py +281 -0
  107. pystatistics-1.0.0/pystatistics/mvnmle/_objectives/parameterizations.py +352 -0
  108. pystatistics-1.0.0/pystatistics/mvnmle/_utils.py +154 -0
  109. pystatistics-1.0.0/pystatistics/mvnmle/backends/__init__.py +8 -0
  110. pystatistics-1.0.0/pystatistics/mvnmle/backends/cpu.py +118 -0
  111. pystatistics-1.0.0/pystatistics/mvnmle/backends/em.py +321 -0
  112. pystatistics-1.0.0/pystatistics/mvnmle/backends/gpu.py +175 -0
  113. pystatistics-1.0.0/pystatistics/mvnmle/datasets.py +47 -0
  114. pystatistics-1.0.0/pystatistics/mvnmle/design.py +169 -0
  115. pystatistics-1.0.0/pystatistics/mvnmle/mcar_test.py +223 -0
  116. pystatistics-1.0.0/pystatistics/mvnmle/patterns.py +226 -0
  117. pystatistics-1.0.0/pystatistics/mvnmle/solution.py +192 -0
  118. pystatistics-1.0.0/pystatistics/mvnmle/solvers.py +188 -0
  119. pystatistics-1.0.0/pystatistics/py.typed +0 -0
  120. pystatistics-1.0.0/pystatistics/regression/__init__.py +49 -0
  121. pystatistics-1.0.0/pystatistics/regression/backends/__init__.py +21 -0
  122. pystatistics-1.0.0/pystatistics/regression/backends/cpu.py +65 -0
  123. pystatistics-1.0.0/pystatistics/regression/backends/cpu_glm.py +297 -0
  124. pystatistics-1.0.0/pystatistics/regression/backends/gpu.py +226 -0
  125. pystatistics-1.0.0/pystatistics/regression/backends/gpu_glm.py +347 -0
  126. pystatistics-1.0.0/pystatistics/regression/design.py +188 -0
  127. pystatistics-1.0.0/pystatistics/regression/families.py +463 -0
  128. pystatistics-1.0.0/pystatistics/regression/solution.py +597 -0
  129. pystatistics-1.0.0/pystatistics/regression/solvers.py +202 -0
  130. pystatistics-1.0.0/pystatistics/survival/__init__.py +33 -0
  131. pystatistics-1.0.0/pystatistics/survival/_common.py +95 -0
  132. pystatistics-1.0.0/pystatistics/survival/_cox.py +384 -0
  133. pystatistics-1.0.0/pystatistics/survival/_discrete.py +200 -0
  134. pystatistics-1.0.0/pystatistics/survival/_km.py +224 -0
  135. pystatistics-1.0.0/pystatistics/survival/_logrank.py +237 -0
  136. pystatistics-1.0.0/pystatistics/survival/backends/__init__.py +5 -0
  137. pystatistics-1.0.0/pystatistics/survival/backends/cpu.py +10 -0
  138. pystatistics-1.0.0/pystatistics/survival/backends/gpu.py +10 -0
  139. pystatistics-1.0.0/pystatistics/survival/design.py +139 -0
  140. pystatistics-1.0.0/pystatistics/survival/solution.py +467 -0
  141. pystatistics-1.0.0/pystatistics/survival/solvers.py +305 -0
  142. pystatistics-1.0.0/tests/anova/__init__.py +0 -0
  143. pystatistics-1.0.0/tests/anova/conftest.py +222 -0
  144. pystatistics-1.0.0/tests/anova/test_contrasts.py +238 -0
  145. pystatistics-1.0.0/tests/anova/test_design.py +153 -0
  146. pystatistics-1.0.0/tests/anova/test_factorial.py +163 -0
  147. pystatistics-1.0.0/tests/anova/test_levene.py +118 -0
  148. pystatistics-1.0.0/tests/anova/test_oneway.py +238 -0
  149. pystatistics-1.0.0/tests/anova/test_posthoc.py +193 -0
  150. pystatistics-1.0.0/tests/anova/test_r_validation.py +545 -0
  151. pystatistics-1.0.0/tests/anova/test_repeated_measures.py +197 -0
  152. pystatistics-1.0.0/tests/benchmark_gpu.py +112 -0
  153. pystatistics-1.0.0/tests/conftest.py +34 -0
  154. pystatistics-1.0.0/tests/core/test_exceptions.py +229 -0
  155. pystatistics-1.0.0/tests/core/test_result.py +289 -0
  156. pystatistics-1.0.0/tests/core/test_validation.py +372 -0
  157. pystatistics-1.0.0/tests/descriptive/__init__.py +0 -0
  158. pystatistics-1.0.0/tests/descriptive/conftest.py +21 -0
  159. pystatistics-1.0.0/tests/descriptive/test_cor.py +278 -0
  160. pystatistics-1.0.0/tests/descriptive/test_cov.py +136 -0
  161. pystatistics-1.0.0/tests/descriptive/test_describe.py +203 -0
  162. pystatistics-1.0.0/tests/descriptive/test_gpu.py +141 -0
  163. pystatistics-1.0.0/tests/descriptive/test_missing.py +91 -0
  164. pystatistics-1.0.0/tests/descriptive/test_moments.py +128 -0
  165. pystatistics-1.0.0/tests/descriptive/test_quantile.py +329 -0
  166. pystatistics-1.0.0/tests/descriptive/test_r_validation.py +309 -0
  167. pystatistics-1.0.0/tests/fixtures/anova_ancova_meta.json +129 -0
  168. pystatistics-1.0.0/tests/fixtures/anova_ancova_r_results.json +8 -0
  169. pystatistics-1.0.0/tests/fixtures/anova_bonferroni_meta.json +97 -0
  170. pystatistics-1.0.0/tests/fixtures/anova_bonferroni_r_results.json +9 -0
  171. pystatistics-1.0.0/tests/fixtures/anova_eta_meta.json +97 -0
  172. pystatistics-1.0.0/tests/fixtures/anova_eta_r_results.json +8 -0
  173. pystatistics-1.0.0/tests/fixtures/anova_levene_meta.json +157 -0
  174. pystatistics-1.0.0/tests/fixtures/anova_levene_r_results.json +8 -0
  175. pystatistics-1.0.0/tests/fixtures/anova_oneway_balanced_meta.json +97 -0
  176. pystatistics-1.0.0/tests/fixtures/anova_oneway_balanced_r_results.json +15 -0
  177. pystatistics-1.0.0/tests/fixtures/anova_oneway_unbalanced_meta.json +87 -0
  178. pystatistics-1.0.0/tests/fixtures/anova_oneway_unbalanced_r_results.json +15 -0
  179. pystatistics-1.0.0/tests/fixtures/anova_rm_mixed_meta.json +254 -0
  180. pystatistics-1.0.0/tests/fixtures/anova_rm_mixed_r_results.json +1 -0
  181. pystatistics-1.0.0/tests/fixtures/anova_rm_within_meta.json +119 -0
  182. pystatistics-1.0.0/tests/fixtures/anova_rm_within_r_results.json +11 -0
  183. pystatistics-1.0.0/tests/fixtures/anova_tukey_meta.json +97 -0
  184. pystatistics-1.0.0/tests/fixtures/anova_tukey_r_results.json +7 -0
  185. pystatistics-1.0.0/tests/fixtures/anova_twoway_balanced_meta.json +189 -0
  186. pystatistics-1.0.0/tests/fixtures/anova_twoway_balanced_r_results.json +18 -0
  187. pystatistics-1.0.0/tests/fixtures/anova_twoway_unbalanced_meta.json +117 -0
  188. pystatistics-1.0.0/tests/fixtures/anova_twoway_unbalanced_r_results.json +18 -0
  189. pystatistics-1.0.0/tests/fixtures/basic_100x3.csv +101 -0
  190. pystatistics-1.0.0/tests/fixtures/basic_100x3_meta.json +13 -0
  191. pystatistics-1.0.0/tests/fixtures/basic_100x3_r_results.json +21 -0
  192. pystatistics-1.0.0/tests/fixtures/collinear_almost.csv +101 -0
  193. pystatistics-1.0.0/tests/fixtures/collinear_almost_meta.json +14 -0
  194. pystatistics-1.0.0/tests/fixtures/collinear_almost_r_results.json +21 -0
  195. pystatistics-1.0.0/tests/fixtures/desc_basic_100x5.csv +101 -0
  196. pystatistics-1.0.0/tests/fixtures/desc_basic_100x5_meta.json +6 -0
  197. pystatistics-1.0.0/tests/fixtures/desc_basic_100x5_r_results.json +38 -0
  198. pystatistics-1.0.0/tests/fixtures/desc_constant_column.csv +41 -0
  199. pystatistics-1.0.0/tests/fixtures/desc_constant_column_meta.json +6 -0
  200. pystatistics-1.0.0/tests/fixtures/desc_constant_column_r_results.json +38 -0
  201. pystatistics-1.0.0/tests/fixtures/desc_extreme_values.csv +51 -0
  202. pystatistics-1.0.0/tests/fixtures/desc_extreme_values_meta.json +6 -0
  203. pystatistics-1.0.0/tests/fixtures/desc_extreme_values_r_results.json +38 -0
  204. pystatistics-1.0.0/tests/fixtures/desc_large_1000x10.csv +1001 -0
  205. pystatistics-1.0.0/tests/fixtures/desc_large_1000x10_meta.json +6 -0
  206. pystatistics-1.0.0/tests/fixtures/desc_large_1000x10_r_results.json +38 -0
  207. pystatistics-1.0.0/tests/fixtures/desc_nan_columnwise.csv +61 -0
  208. pystatistics-1.0.0/tests/fixtures/desc_nan_columnwise_meta.json +6 -0
  209. pystatistics-1.0.0/tests/fixtures/desc_nan_columnwise_r_results.json +38 -0
  210. pystatistics-1.0.0/tests/fixtures/desc_nan_scattered.csv +51 -0
  211. pystatistics-1.0.0/tests/fixtures/desc_nan_scattered_meta.json +6 -0
  212. pystatistics-1.0.0/tests/fixtures/desc_nan_scattered_r_results.json +38 -0
  213. pystatistics-1.0.0/tests/fixtures/desc_negative_correlation.csv +101 -0
  214. pystatistics-1.0.0/tests/fixtures/desc_negative_correlation_meta.json +6 -0
  215. pystatistics-1.0.0/tests/fixtures/desc_negative_correlation_r_results.json +38 -0
  216. pystatistics-1.0.0/tests/fixtures/desc_perfect_correlation.csv +51 -0
  217. pystatistics-1.0.0/tests/fixtures/desc_perfect_correlation_meta.json +6 -0
  218. pystatistics-1.0.0/tests/fixtures/desc_perfect_correlation_r_results.json +38 -0
  219. pystatistics-1.0.0/tests/fixtures/desc_single_column.csv +31 -0
  220. pystatistics-1.0.0/tests/fixtures/desc_single_column_meta.json +6 -0
  221. pystatistics-1.0.0/tests/fixtures/desc_single_column_r_results.json +38 -0
  222. pystatistics-1.0.0/tests/fixtures/desc_ties.csv +81 -0
  223. pystatistics-1.0.0/tests/fixtures/desc_ties_meta.json +6 -0
  224. pystatistics-1.0.0/tests/fixtures/desc_ties_r_results.json +38 -0
  225. pystatistics-1.0.0/tests/fixtures/different_scales.csv +101 -0
  226. pystatistics-1.0.0/tests/fixtures/different_scales_meta.json +14 -0
  227. pystatistics-1.0.0/tests/fixtures/different_scales_r_results.json +21 -0
  228. pystatistics-1.0.0/tests/fixtures/generate_anova_fixtures.py +360 -0
  229. pystatistics-1.0.0/tests/fixtures/generate_descriptive_fixtures.py +236 -0
  230. pystatistics-1.0.0/tests/fixtures/generate_fixtures.py +280 -0
  231. pystatistics-1.0.0/tests/fixtures/generate_glm_fixtures.py +294 -0
  232. pystatistics-1.0.0/tests/fixtures/generate_hypothesis_fixtures.py +234 -0
  233. pystatistics-1.0.0/tests/fixtures/generate_mixed_fixtures.py +228 -0
  234. pystatistics-1.0.0/tests/fixtures/generate_montecarlo_fixtures.py +257 -0
  235. pystatistics-1.0.0/tests/fixtures/generate_survival_fixtures.py +264 -0
  236. pystatistics-1.0.0/tests/fixtures/glm_binomial_balanced.csv +501 -0
  237. pystatistics-1.0.0/tests/fixtures/glm_binomial_balanced_meta.json +16 -0
  238. pystatistics-1.0.0/tests/fixtures/glm_binomial_balanced_r_results.json +25 -0
  239. pystatistics-1.0.0/tests/fixtures/glm_binomial_basic.csv +201 -0
  240. pystatistics-1.0.0/tests/fixtures/glm_binomial_basic_meta.json +14 -0
  241. pystatistics-1.0.0/tests/fixtures/glm_binomial_basic_r_results.json +25 -0
  242. pystatistics-1.0.0/tests/fixtures/glm_binomial_large.csv +5001 -0
  243. pystatistics-1.0.0/tests/fixtures/glm_binomial_large_meta.json +21 -0
  244. pystatistics-1.0.0/tests/fixtures/glm_binomial_large_r_results.json +25 -0
  245. pystatistics-1.0.0/tests/fixtures/glm_binomial_separated.csv +101 -0
  246. pystatistics-1.0.0/tests/fixtures/glm_binomial_separated_meta.json +13 -0
  247. pystatistics-1.0.0/tests/fixtures/glm_binomial_separated_r_results.json +25 -0
  248. pystatistics-1.0.0/tests/fixtures/glm_gaussian_basic.csv +101 -0
  249. pystatistics-1.0.0/tests/fixtures/glm_gaussian_basic_meta.json +14 -0
  250. pystatistics-1.0.0/tests/fixtures/glm_gaussian_basic_r_results.json +25 -0
  251. pystatistics-1.0.0/tests/fixtures/glm_gaussian_large.csv +5001 -0
  252. pystatistics-1.0.0/tests/fixtures/glm_gaussian_large_meta.json +21 -0
  253. pystatistics-1.0.0/tests/fixtures/glm_gaussian_large_r_results.json +25 -0
  254. pystatistics-1.0.0/tests/fixtures/glm_poisson_basic.csv +201 -0
  255. pystatistics-1.0.0/tests/fixtures/glm_poisson_basic_meta.json +14 -0
  256. pystatistics-1.0.0/tests/fixtures/glm_poisson_basic_r_results.json +25 -0
  257. pystatistics-1.0.0/tests/fixtures/glm_poisson_large_counts.csv +301 -0
  258. pystatistics-1.0.0/tests/fixtures/glm_poisson_large_counts_meta.json +15 -0
  259. pystatistics-1.0.0/tests/fixtures/glm_poisson_large_counts_r_results.json +25 -0
  260. pystatistics-1.0.0/tests/fixtures/glm_poisson_zeros.csv +201 -0
  261. pystatistics-1.0.0/tests/fixtures/glm_poisson_zeros_meta.json +15 -0
  262. pystatistics-1.0.0/tests/fixtures/glm_poisson_zeros_r_results.json +25 -0
  263. pystatistics-1.0.0/tests/fixtures/high_noise.csv +101 -0
  264. pystatistics-1.0.0/tests/fixtures/high_noise_meta.json +14 -0
  265. pystatistics-1.0.0/tests/fixtures/high_noise_r_results.json +21 -0
  266. pystatistics-1.0.0/tests/fixtures/htest_chisq_2x2_yates_meta.json +19 -0
  267. pystatistics-1.0.0/tests/fixtures/htest_chisq_2x2_yates_r_results.json +10 -0
  268. pystatistics-1.0.0/tests/fixtures/htest_chisq_3x3_meta.json +26 -0
  269. pystatistics-1.0.0/tests/fixtures/htest_chisq_3x3_r_results.json +10 -0
  270. pystatistics-1.0.0/tests/fixtures/htest_chisq_gof_meta.json +24 -0
  271. pystatistics-1.0.0/tests/fixtures/htest_chisq_gof_r_results.json +10 -0
  272. pystatistics-1.0.0/tests/fixtures/htest_chisq_gof_unequal_meta.json +20 -0
  273. pystatistics-1.0.0/tests/fixtures/htest_chisq_gof_unequal_r_results.json +10 -0
  274. pystatistics-1.0.0/tests/fixtures/htest_fisher_2x2_less_meta.json +20 -0
  275. pystatistics-1.0.0/tests/fixtures/htest_fisher_2x2_less_r_results.json +14 -0
  276. pystatistics-1.0.0/tests/fixtures/htest_fisher_2x2_meta.json +20 -0
  277. pystatistics-1.0.0/tests/fixtures/htest_fisher_2x2_r_results.json +14 -0
  278. pystatistics-1.0.0/tests/fixtures/htest_fisher_3x3_meta.json +27 -0
  279. pystatistics-1.0.0/tests/fixtures/htest_fisher_3x3_r_results.json +6 -0
  280. pystatistics-1.0.0/tests/fixtures/htest_ks_onesample_norm_meta.json +33 -0
  281. pystatistics-1.0.0/tests/fixtures/htest_ks_onesample_norm_r_results.json +8 -0
  282. pystatistics-1.0.0/tests/fixtures/htest_ks_twosample_meta.json +68 -0
  283. pystatistics-1.0.0/tests/fixtures/htest_ks_twosample_r_results.json +8 -0
  284. pystatistics-1.0.0/tests/fixtures/htest_prop_onesample_meta.json +18 -0
  285. pystatistics-1.0.0/tests/fixtures/htest_prop_onesample_r_results.json +19 -0
  286. pystatistics-1.0.0/tests/fixtures/htest_prop_twosample_meta.json +19 -0
  287. pystatistics-1.0.0/tests/fixtures/htest_prop_twosample_r_results.json +17 -0
  288. pystatistics-1.0.0/tests/fixtures/htest_t_onesample_meta.json +33 -0
  289. pystatistics-1.0.0/tests/fixtures/htest_t_onesample_r_results.json +19 -0
  290. pystatistics-1.0.0/tests/fixtures/htest_t_paired_meta.json +46 -0
  291. pystatistics-1.0.0/tests/fixtures/htest_t_paired_r_results.json +19 -0
  292. pystatistics-1.0.0/tests/fixtures/htest_t_pooled_meta.json +56 -0
  293. pystatistics-1.0.0/tests/fixtures/htest_t_pooled_r_results.json +20 -0
  294. pystatistics-1.0.0/tests/fixtures/htest_t_welch_meta.json +71 -0
  295. pystatistics-1.0.0/tests/fixtures/htest_t_welch_r_results.json +20 -0
  296. pystatistics-1.0.0/tests/fixtures/htest_var_basic_meta.json +60 -0
  297. pystatistics-1.0.0/tests/fixtures/htest_var_basic_r_results.json +20 -0
  298. pystatistics-1.0.0/tests/fixtures/htest_wilcox_ranksum_meta.json +28 -0
  299. pystatistics-1.0.0/tests/fixtures/htest_wilcox_ranksum_r_results.json +16 -0
  300. pystatistics-1.0.0/tests/fixtures/htest_wilcox_signed_meta.json +24 -0
  301. pystatistics-1.0.0/tests/fixtures/htest_wilcox_signed_r_results.json +16 -0
  302. pystatistics-1.0.0/tests/fixtures/ill_conditioned.csv +101 -0
  303. pystatistics-1.0.0/tests/fixtures/ill_conditioned_meta.json +17 -0
  304. pystatistics-1.0.0/tests/fixtures/ill_conditioned_r_results.json +21 -0
  305. pystatistics-1.0.0/tests/fixtures/large_coeffs.csv +101 -0
  306. pystatistics-1.0.0/tests/fixtures/large_coeffs_meta.json +13 -0
  307. pystatistics-1.0.0/tests/fixtures/large_coeffs_r_results.json +21 -0
  308. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_90_meta.json +117 -0
  309. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_90_r_results.json +16 -0
  310. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_normal_meta.json +67 -0
  311. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_normal_r_results.json +16 -0
  312. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_skewed_meta.json +77 -0
  313. pystatistics-1.0.0/tests/fixtures/mc_boot_ci_skewed_r_results.json +16 -0
  314. pystatistics-1.0.0/tests/fixtures/mc_boot_mean_balanced_meta.json +40 -0
  315. pystatistics-1.0.0/tests/fixtures/mc_boot_mean_balanced_r_results.json +9 -0
  316. pystatistics-1.0.0/tests/fixtures/mc_boot_mean_ordinary_meta.json +40 -0
  317. pystatistics-1.0.0/tests/fixtures/mc_boot_mean_ordinary_r_results.json +9 -0
  318. pystatistics-1.0.0/tests/fixtures/mc_boot_median_meta.json +50 -0
  319. pystatistics-1.0.0/tests/fixtures/mc_boot_median_r_results.json +9 -0
  320. pystatistics-1.0.0/tests/fixtures/mc_boot_variance_meta.json +60 -0
  321. pystatistics-1.0.0/tests/fixtures/mc_boot_variance_r_results.json +9 -0
  322. pystatistics-1.0.0/tests/fixtures/mc_perm_greater_meta.json +61 -0
  323. pystatistics-1.0.0/tests/fixtures/mc_perm_greater_r_results.json +9 -0
  324. pystatistics-1.0.0/tests/fixtures/mc_perm_not_significant_meta.json +71 -0
  325. pystatistics-1.0.0/tests/fixtures/mc_perm_not_significant_r_results.json +9 -0
  326. pystatistics-1.0.0/tests/fixtures/mc_perm_significant_meta.json +71 -0
  327. pystatistics-1.0.0/tests/fixtures/mc_perm_significant_r_results.json +9 -0
  328. pystatistics-1.0.0/tests/fixtures/mixed/glmm_binomial.csv +401 -0
  329. pystatistics-1.0.0/tests/fixtures/mixed/glmm_poisson.csv +301 -0
  330. pystatistics-1.0.0/tests/fixtures/mixed/lmm_crossed.csv +161 -0
  331. pystatistics-1.0.0/tests/fixtures/mixed/lmm_intercept.csv +121 -0
  332. pystatistics-1.0.0/tests/fixtures/mixed/lmm_ml.csv +121 -0
  333. pystatistics-1.0.0/tests/fixtures/mixed/lmm_no_effect.csv +101 -0
  334. pystatistics-1.0.0/tests/fixtures/mixed/lmm_slope.csv +181 -0
  335. pystatistics-1.0.0/tests/fixtures/mixed/mixed_meta.json +66 -0
  336. pystatistics-1.0.0/tests/fixtures/mixed/mixed_r_results.json +1 -0
  337. pystatistics-1.0.0/tests/fixtures/near_square.csv +51 -0
  338. pystatistics-1.0.0/tests/fixtures/near_square_meta.json +55 -0
  339. pystatistics-1.0.0/tests/fixtures/near_square_r_results.json +21 -0
  340. pystatistics-1.0.0/tests/fixtures/no_intercept.csv +101 -0
  341. pystatistics-1.0.0/tests/fixtures/no_intercept_meta.json +14 -0
  342. pystatistics-1.0.0/tests/fixtures/no_intercept_r_results.json +21 -0
  343. pystatistics-1.0.0/tests/fixtures/run_r_anova_validation.R +319 -0
  344. pystatistics-1.0.0/tests/fixtures/run_r_descriptive_validation.R +162 -0
  345. pystatistics-1.0.0/tests/fixtures/run_r_glm_validation.R +174 -0
  346. pystatistics-1.0.0/tests/fixtures/run_r_hypothesis_validation.R +201 -0
  347. pystatistics-1.0.0/tests/fixtures/run_r_mixed_validation.R +183 -0
  348. pystatistics-1.0.0/tests/fixtures/run_r_montecarlo_validation.R +204 -0
  349. pystatistics-1.0.0/tests/fixtures/run_r_survival_validation.R +131 -0
  350. pystatistics-1.0.0/tests/fixtures/run_r_validation.R +123 -0
  351. pystatistics-1.0.0/tests/fixtures/run_validation.sh +30 -0
  352. pystatistics-1.0.0/tests/fixtures/small_noise.csv +101 -0
  353. pystatistics-1.0.0/tests/fixtures/small_noise_meta.json +14 -0
  354. pystatistics-1.0.0/tests/fixtures/small_noise_r_results.json +21 -0
  355. pystatistics-1.0.0/tests/fixtures/surv_cox_breslow_meta.json +160 -0
  356. pystatistics-1.0.0/tests/fixtures/surv_cox_breslow_r_results.json +13 -0
  357. pystatistics-1.0.0/tests/fixtures/surv_cox_single_meta.json +160 -0
  358. pystatistics-1.0.0/tests/fixtures/surv_cox_single_r_results.json +13 -0
  359. pystatistics-1.0.0/tests/fixtures/surv_cox_ties_meta.json +110 -0
  360. pystatistics-1.0.0/tests/fixtures/surv_cox_ties_r_results.json +13 -0
  361. pystatistics-1.0.0/tests/fixtures/surv_cox_two_cov_meta.json +250 -0
  362. pystatistics-1.0.0/tests/fixtures/surv_cox_two_cov_r_results.json +13 -0
  363. pystatistics-1.0.0/tests/fixtures/surv_km_basic_meta.json +29 -0
  364. pystatistics-1.0.0/tests/fixtures/surv_km_basic_r_results.json +13 -0
  365. pystatistics-1.0.0/tests/fixtures/surv_km_heavy_cens_meta.json +49 -0
  366. pystatistics-1.0.0/tests/fixtures/surv_km_heavy_cens_r_results.json +13 -0
  367. pystatistics-1.0.0/tests/fixtures/surv_km_loglog_ci_meta.json +29 -0
  368. pystatistics-1.0.0/tests/fixtures/surv_km_loglog_ci_r_results.json +13 -0
  369. pystatistics-1.0.0/tests/fixtures/surv_km_no_cens_meta.json +29 -0
  370. pystatistics-1.0.0/tests/fixtures/surv_km_no_cens_r_results.json +13 -0
  371. pystatistics-1.0.0/tests/fixtures/surv_km_plain_ci_meta.json +29 -0
  372. pystatistics-1.0.0/tests/fixtures/surv_km_plain_ci_r_results.json +13 -0
  373. pystatistics-1.0.0/tests/fixtures/surv_km_ties_meta.json +29 -0
  374. pystatistics-1.0.0/tests/fixtures/surv_km_ties_r_results.json +13 -0
  375. pystatistics-1.0.0/tests/fixtures/surv_lr_peto_meta.json +52 -0
  376. pystatistics-1.0.0/tests/fixtures/surv_lr_peto_r_results.json +8 -0
  377. pystatistics-1.0.0/tests/fixtures/surv_lr_three_group_meta.json +64 -0
  378. pystatistics-1.0.0/tests/fixtures/surv_lr_three_group_r_results.json +8 -0
  379. pystatistics-1.0.0/tests/fixtures/surv_lr_two_group_meta.json +52 -0
  380. pystatistics-1.0.0/tests/fixtures/surv_lr_two_group_r_results.json +8 -0
  381. pystatistics-1.0.0/tests/fixtures/tall_skinny.csv +1001 -0
  382. pystatistics-1.0.0/tests/fixtures/tall_skinny_meta.json +15 -0
  383. pystatistics-1.0.0/tests/fixtures/tall_skinny_r_results.json +21 -0
  384. pystatistics-1.0.0/tests/fixtures/validate_against_r.py +257 -0
  385. pystatistics-1.0.0/tests/hypothesis/__init__.py +0 -0
  386. pystatistics-1.0.0/tests/hypothesis/conftest.py +21 -0
  387. pystatistics-1.0.0/tests/hypothesis/test_chisq_test.py +202 -0
  388. pystatistics-1.0.0/tests/hypothesis/test_fisher_test.py +201 -0
  389. pystatistics-1.0.0/tests/hypothesis/test_gpu.py +144 -0
  390. pystatistics-1.0.0/tests/hypothesis/test_ks_test.py +195 -0
  391. pystatistics-1.0.0/tests/hypothesis/test_p_adjust.py +156 -0
  392. pystatistics-1.0.0/tests/hypothesis/test_prop_test.py +216 -0
  393. pystatistics-1.0.0/tests/hypothesis/test_r_validation.py +339 -0
  394. pystatistics-1.0.0/tests/hypothesis/test_t_test.py +198 -0
  395. pystatistics-1.0.0/tests/hypothesis/test_var_test.py +188 -0
  396. pystatistics-1.0.0/tests/hypothesis/test_wilcox_test.py +165 -0
  397. pystatistics-1.0.0/tests/mixed/__init__.py +0 -0
  398. pystatistics-1.0.0/tests/mixed/conftest.py +244 -0
  399. pystatistics-1.0.0/tests/mixed/test_glmm.py +169 -0
  400. pystatistics-1.0.0/tests/mixed/test_lmm_crossed.py +83 -0
  401. pystatistics-1.0.0/tests/mixed/test_lmm_intercept.py +166 -0
  402. pystatistics-1.0.0/tests/mixed/test_lmm_nested.py +74 -0
  403. pystatistics-1.0.0/tests/mixed/test_lmm_slope.py +103 -0
  404. pystatistics-1.0.0/tests/mixed/test_pls.py +130 -0
  405. pystatistics-1.0.0/tests/mixed/test_r_validation.py +708 -0
  406. pystatistics-1.0.0/tests/mixed/test_random_effects.py +253 -0
  407. pystatistics-1.0.0/tests/mixed/test_satterthwaite.py +71 -0
  408. pystatistics-1.0.0/tests/montecarlo/__init__.py +0 -0
  409. pystatistics-1.0.0/tests/montecarlo/conftest.py +21 -0
  410. pystatistics-1.0.0/tests/montecarlo/test_batched_solver.py +187 -0
  411. pystatistics-1.0.0/tests/montecarlo/test_boot_ci.py +279 -0
  412. pystatistics-1.0.0/tests/montecarlo/test_bootstrap.py +488 -0
  413. pystatistics-1.0.0/tests/montecarlo/test_gpu.py +293 -0
  414. pystatistics-1.0.0/tests/montecarlo/test_influence.py +85 -0
  415. pystatistics-1.0.0/tests/montecarlo/test_permutation.py +227 -0
  416. pystatistics-1.0.0/tests/montecarlo/test_r_validation.py +395 -0
  417. pystatistics-1.0.0/tests/mvnmle/references/apple_em_reference.json +1 -0
  418. pystatistics-1.0.0/tests/mvnmle/references/apple_reference.json +12 -0
  419. pystatistics-1.0.0/tests/mvnmle/references/generate_em_fixtures.R +128 -0
  420. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_apple.json +30 -0
  421. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_complete.json +14 -0
  422. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_extreme.json +10 -0
  423. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_missvals.json +10 -0
  424. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_simple_mcar.json +50 -0
  425. pystatistics-1.0.0/tests/mvnmle/references/little_mcar_summary.json +41 -0
  426. pystatistics-1.0.0/tests/mvnmle/references/missvals_em_reference.json +1 -0
  427. pystatistics-1.0.0/tests/mvnmle/references/missvals_reference.json +15 -0
  428. pystatistics-1.0.0/tests/mvnmle/references/small_test_reference.json +29 -0
  429. pystatistics-1.0.0/tests/mvnmle/test_em.py +302 -0
  430. pystatistics-1.0.0/tests/mvnmle/test_gpu.py +333 -0
  431. pystatistics-1.0.0/tests/mvnmle/test_mlest.py +222 -0
  432. pystatistics-1.0.0/tests/regression/benchmark.py +29 -0
  433. pystatistics-1.0.0/tests/regression/benchmark.r +26 -0
  434. pystatistics-1.0.0/tests/regression/conftest.py +30 -0
  435. pystatistics-1.0.0/tests/regression/test_fit.py +247 -0
  436. pystatistics-1.0.0/tests/regression/test_glm.py +375 -0
  437. pystatistics-1.0.0/tests/regression/test_glm_gpu.py +331 -0
  438. pystatistics-1.0.0/tests/regression/test_glm_r_validation.py +231 -0
  439. pystatistics-1.0.0/tests/regression/test_r_validation.py +165 -0
  440. pystatistics-1.0.0/tests/regression/test_stress_gpu.py +345 -0
  441. pystatistics-1.0.0/tests/survival/__init__.py +0 -0
  442. pystatistics-1.0.0/tests/survival/conftest.py +21 -0
  443. pystatistics-1.0.0/tests/survival/test_coxph.py +356 -0
  444. pystatistics-1.0.0/tests/survival/test_discrete_time.py +233 -0
  445. pystatistics-1.0.0/tests/survival/test_gpu.py +91 -0
  446. pystatistics-1.0.0/tests/survival/test_kaplan_meier.py +637 -0
  447. pystatistics-1.0.0/tests/survival/test_logrank.py +244 -0
  448. pystatistics-1.0.0/tests/survival/test_r_validation.py +278 -0
@@ -0,0 +1,45 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ build:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+
19
+ - name: Install build tools
20
+ run: pip install build
21
+
22
+ - name: Build sdist and wheel
23
+ run: python -m build
24
+
25
+ - name: Upload build artifacts
26
+ uses: actions/upload-artifact@v4
27
+ with:
28
+ name: dist
29
+ path: dist/
30
+
31
+ publish-pypi:
32
+ needs: build
33
+ runs-on: ubuntu-latest
34
+ environment: pypi
35
+ permissions:
36
+ id-token: write
37
+ steps:
38
+ - name: Download build artifacts
39
+ uses: actions/download-artifact@v4
40
+ with:
41
+ name: dist
42
+ path: dist/
43
+
44
+ - name: Publish to PyPI
45
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,116 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ *.manifest
29
+ *.spec
30
+
31
+ # Installer logs
32
+ pip-log.txt
33
+ pip-delete-this-directory.txt
34
+
35
+ # Unit test / coverage reports
36
+ htmlcov/
37
+ .tox/
38
+ .nox/
39
+ .coverage
40
+ .coverage.*
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+ *.cover
45
+ *.py,cover
46
+ .hypothesis/
47
+ .pytest_cache/
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Sphinx documentation
54
+ docs/_build/
55
+
56
+ # PyBuilder
57
+ target/
58
+
59
+ # Jupyter Notebook
60
+ .ipynb_checkpoints
61
+
62
+ # IPython
63
+ profile_default/
64
+ ipython_config.py
65
+
66
+ # pyenv
67
+ .python-version
68
+
69
+ # Environments
70
+ .env
71
+ .venv
72
+ env/
73
+ venv/
74
+ ENV/
75
+ env.bak/
76
+ venv.bak/
77
+
78
+ # Spyder project settings
79
+ .spyderproject
80
+ .spyproject
81
+
82
+ # Rope project settings
83
+ .ropeproject
84
+
85
+ # mypy
86
+ .mypy_cache/
87
+ .dmypy.json
88
+ dmypy.json
89
+
90
+ # Ruff
91
+ .ruff_cache/
92
+
93
+ # IDE
94
+ .idea/
95
+ .vscode/
96
+ *.swp
97
+ *.swo
98
+ *~
99
+
100
+ # OS
101
+ .DS_Store
102
+ Thumbs.db
103
+
104
+ # Project specific
105
+ *.log
106
+ .benchmarks/
107
+ fixtures/*.pkl
108
+
109
+ # Large binary / data files (blacklist specific patterns, not all JSON/CSV)
110
+ *.h5
111
+ *.pkl
112
+
113
+ # Fixture CSVs and JSONs ARE tracked — they're small test data.
114
+ # Only block genuinely large generated artifacts:
115
+ benchmarks/**/*.csv
116
+ benchmarks/**/*.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hai-Shuo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.4
2
+ Name: pystatistics
3
+ Version: 1.0.0
4
+ Summary: GPU-accelerated statistical computing for Python
5
+ Project-URL: Homepage, https://sgcx.org/technology/pystatistics/
6
+ Project-URL: Documentation, https://sgcx.org/docs/pystatistics/
7
+ Project-URL: Repository, https://github.com/sgcx-org/pystatistics
8
+ Project-URL: Issues, https://github.com/sgcx-org/pystatistics/issues
9
+ Author-email: Hai-Shuo <contact@sgcx.org>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: biostatistics,clinical-trials,gpu,maximum-likelihood,regression,statistics
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
22
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: numpy>=1.24
26
+ Requires-Dist: scipy>=1.10
27
+ Provides-Extra: all
28
+ Requires-Dist: furo; extra == 'all'
29
+ Requires-Dist: mypy>=1.0; extra == 'all'
30
+ Requires-Dist: pytest-cov>=4.0; extra == 'all'
31
+ Requires-Dist: pytest>=7.0; extra == 'all'
32
+ Requires-Dist: ruff>=0.1; extra == 'all'
33
+ Requires-Dist: sphinx>=6.0; extra == 'all'
34
+ Requires-Dist: torch>=2.0; extra == 'all'
35
+ Provides-Extra: dev
36
+ Requires-Dist: mypy>=1.0; extra == 'dev'
37
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
38
+ Requires-Dist: pytest>=7.0; extra == 'dev'
39
+ Requires-Dist: ruff>=0.1; extra == 'dev'
40
+ Provides-Extra: docs
41
+ Requires-Dist: furo; extra == 'docs'
42
+ Requires-Dist: sphinx>=6.0; extra == 'docs'
43
+ Provides-Extra: gpu
44
+ Requires-Dist: torch>=2.0; extra == 'gpu'
45
+ Description-Content-Type: text/markdown
46
+
47
+ # PyStatistics
48
+
49
+ GPU-accelerated statistical computing for Python.
50
+
51
+ ---
52
+
53
+ ## Design Philosophy
54
+
55
+ PyStatistics maintains two parallel computational paths with distinct goals:
56
+
57
+ - **CPU implementations aim for R-level reproducibility.** CPU backends are validated against R reference implementations to near machine precision (rtol = 1e-10). When a CPU result disagrees with R, PyStatistics has a bug.
58
+
59
+ - **GPU implementations prioritize modern numerical performance and scalability.** GPU backends use FP32 arithmetic and algorithms optimized for throughput. They are validated against CPU backends, not directly against R.
60
+
61
+ - **Divergence between CPU and GPU outputs may occur due to floating-point precision, algorithmic differences, or both.** This is by design, not a defect. The section below specifies exactly how much divergence is acceptable.
62
+
63
+ ### Operating Principles
64
+
65
+ 1. **Correctness > Fidelity > Performance > Convenience**
66
+ 2. **Fail fast, fail loud** — no silent fallbacks or "helpful" defaults
67
+ 3. **Explicit over implicit** — require parameters, don't assume intent
68
+ 4. **Two-tier validation** — CPU vs R, then GPU vs CPU
69
+
70
+ ---
71
+
72
+ ## Statistical Equivalence: GPU vs CPU
73
+
74
+ GPU backends produce results in FP32 (single precision) while CPU backends use FP64 (double precision). This section defines exactly what "statistically equivalent" means and when it breaks down.
75
+
76
+ All tolerances below are relative (`rtol`) unless stated otherwise. They apply to **well-conditioned problems** (condition number < 10^6) at **moderate scale** (n < 1M, p < 1000). Degradation at larger scale or worse conditioning is documented below.
77
+
78
+ ### Tier 1: Parameter Estimates
79
+
80
+ | Quantity | Tolerance | Notes |
81
+ |----------|-----------|-------|
82
+ | Coefficients / means | rtol <= 1e-3 | Tightest at ~1e-4 for simple LM |
83
+ | Fitted values | rtol <= 1e-3 | Directly derived from coefficients |
84
+ | GPU-CPU correlation | > 0.9999 | Binding constraint at all scales |
85
+
86
+ ### Tier 2: Uncertainty Estimates
87
+
88
+ | Quantity | Tolerance | Notes |
89
+ |----------|-----------|-------|
90
+ | Standard errors | rtol <= 1e-2 | Computed from (X'WX)^-1 which amplifies FP32 rounding |
91
+ | Covariance matrices (MLE) | rtol <= 5e-2 | Hessian inversion is sensitive to precision |
92
+
93
+ Standard errors are the weakest link in the GPU pipeline. They depend on the inverse of X'WX (or X'X for LM), which squares the condition number. A well-conditioned problem at FP64 can become a poorly-conditioned inversion at FP32.
94
+
95
+ ### Tier 3: Model Fit Statistics
96
+
97
+ | Quantity | Tolerance | Notes |
98
+ |----------|-----------|-------|
99
+ | Deviance | rtol <= 1e-4 | Scalar reduction — tightest GPU metric |
100
+ | Log-likelihood | abs <= 1.0 | Absolute, not relative (log scale) |
101
+ | AIC / BIC values | rtol <= 1e-3 | Derived from log-likelihood + rank |
102
+ | R-squared (LM) | rtol <= 1e-3 | Ratio of reductions |
103
+
104
+ ### Tier 4: Inference Decisions
105
+
106
+ | Quantity | Guarantee | Notes |
107
+ |----------|-----------|-------|
108
+ | Model ranking under AIC/BIC | Identical | For models with AIC/BIC gap > 2 |
109
+ | Rejection at alpha = 0.05 | Identical | For p-values outside [0.01, 0.10] |
110
+ | Rejection at alpha = 0.05 | Not guaranteed | For p-values in [0.01, 0.10] ("boundary zone") |
111
+
112
+ The boundary zone exists because a ~1% relative difference in a test statistic near the critical value can flip a rejection decision. This is inherent to FP32, not a software defect. If a p-value falls in the boundary zone, use the CPU backend for the definitive answer.
113
+
114
+ ### When Guarantees Degrade
115
+
116
+ **Large scale (n > 1M):** FP32 accumulation over millions of rows introduces drift. Element-wise tolerance relaxes to rtol = 1e-2, but correlation remains > 0.9999. This means GPU coefficients track CPU coefficients nearly perfectly in direction, with small magnitude drift from accumulated rounding.
117
+
118
+ **Ill-conditioned problems (condition number > 10^6):** The GPU backend refuses by default and raises `NumericalError`. Passing `force=True` overrides this, but no numerical guarantees apply. Use the CPU backend for ill-conditioned problems.
119
+
120
+ **Pathological missing data patterns (MLE):** FP32 L-BFGS-B optimization can stall in near-flat regions of the likelihood surface. Means may deviate by up to rtol = 0.5 in extreme cases. The GPU backend will issue a convergence warning. Use the CPU backend for complex missingness patterns.
121
+
122
+ ### Why FP32?
123
+
124
+ Consumer GPUs (NVIDIA RTX series) execute FP32 at 5-10x the throughput of FP64. Apple Silicon GPUs (MPS) do not support FP64 at all. FP32 is the only path to practical GPU acceleration on hardware that researchers actually have. The tolerances above are the honest cost of that acceleration.
125
+
126
+ ---
127
+
128
+ ## Quick Start
129
+
130
+ ```python
131
+ import numpy as np
132
+
133
+ # --- Descriptive statistics ---
134
+ from pystatistics.descriptive import describe, cor, quantile
135
+
136
+ data = np.random.randn(1000, 5)
137
+ result = describe(data)
138
+ print(result.mean, result.sd, result.skewness, result.kurtosis)
139
+
140
+ # Correlation (Pearson, Spearman, Kendall)
141
+ r = cor(data, method='spearman')
142
+ print(r.correlation_matrix)
143
+
144
+ # Quantiles (all 9 R types supported)
145
+ q = quantile(data, type=7)
146
+ print(q.quantiles)
147
+
148
+ # --- Hypothesis testing ---
149
+ from pystatistics.hypothesis import t_test, chisq_test, p_adjust
150
+
151
+ result = t_test([1,2,3,4,5], [3,4,5,6,7])
152
+ print(result.statistic, result.p_value, result.conf_int)
153
+ print(result.summary()) # R-style print.htest output
154
+
155
+ # Multiple testing correction
156
+ p_adjusted = p_adjust([0.01, 0.04, 0.03, 0.005], method='BH')
157
+
158
+ # --- Linear regression ---
159
+ from pystatistics.regression import fit
160
+
161
+ X = np.random.randn(1000, 5)
162
+ y = X @ [1, 2, 3, -1, 0.5] + np.random.randn(1000) * 0.1
163
+ result = fit(X, y)
164
+ print(result.summary())
165
+
166
+ # Logistic regression
167
+ y_binary = (X @ [1, -1, 0.5, 0, 0] + np.random.randn(1000) > 0).astype(float)
168
+ result = fit(X, y_binary, family='binomial')
169
+ print(result.summary())
170
+
171
+ # GPU acceleration (any model)
172
+ result = fit(X, y, backend='gpu')
173
+
174
+ # --- Monte Carlo methods ---
175
+ from pystatistics.montecarlo import boot, boot_ci, permutation_test
176
+
177
+ # Bootstrap for the mean
178
+ data = np.random.randn(100)
179
+ def mean_stat(data, indices):
180
+ return np.array([np.mean(data[indices])])
181
+
182
+ result = boot(data, mean_stat, R=2000, seed=42)
183
+ print(result.t0, result.bias, result.se)
184
+
185
+ # Bootstrap confidence intervals (all 5 types)
186
+ ci_result = boot_ci(result, type='all')
187
+ print(ci_result.ci['perc']) # percentile CI
188
+ print(ci_result.ci['bca']) # BCa CI
189
+
190
+ # Permutation test
191
+ x = np.random.randn(30)
192
+ y = np.random.randn(30) + 1.0
193
+ def mean_diff(x, y): return np.mean(x) - np.mean(y)
194
+ result = permutation_test(x, y, mean_diff, R=9999, seed=42)
195
+ print(result.p_value, result.summary())
196
+
197
+ # --- Survival analysis ---
198
+ from pystatistics.survival import kaplan_meier, survdiff, coxph, discrete_time
199
+
200
+ time = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
201
+ event = np.array([1, 0, 1, 1, 0, 1, 1, 0, 1, 1])
202
+
203
+ # Kaplan-Meier survival curve
204
+ km = kaplan_meier(time, event)
205
+ print(km.survival, km.se, km.ci_lower, km.ci_upper)
206
+
207
+ # Log-rank test (compare groups)
208
+ group = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
209
+ lr = survdiff(time, event, group)
210
+ print(lr.statistic, lr.p_value, lr.summary())
211
+
212
+ # Cox proportional hazards (CPU only)
213
+ X = np.column_stack([np.random.randn(10)])
214
+ cox = coxph(time, event, X)
215
+ print(cox.coefficients, cox.hazard_ratios, cox.summary())
216
+
217
+ # Discrete-time survival (GPU-accelerated)
218
+ dt = discrete_time(time, event, X, backend='auto')
219
+ print(dt.coefficients, dt.hazard_ratios, dt.baseline_hazard)
220
+
221
+ # --- ANOVA ---
222
+ from pystatistics.anova import anova_oneway, anova, anova_rm, anova_posthoc, levene_test
223
+
224
+ # One-way ANOVA
225
+ y = np.concatenate([np.random.randn(20) + mu for mu in [0, 1, 3]])
226
+ group = np.array(['A']*20 + ['B']*20 + ['C']*20)
227
+ result = anova_oneway(y, group)
228
+ print(result.summary()) # R-style ANOVA table
229
+ print(result.eta_squared) # effect sizes
230
+
231
+ # Post-hoc: Tukey HSD
232
+ posthoc = anova_posthoc(result, method='tukey')
233
+ print(posthoc.summary()) # pairwise comparisons with adjusted p-values
234
+
235
+ # Factorial ANOVA (Type II SS, matches R's car::Anova)
236
+ result = anova(y, {'treatment': tx, 'dose': dose}, ss_type=2)
237
+
238
+ # ANCOVA (continuous covariate)
239
+ result = anova(y, {'group': group}, covariates={'age': age}, ss_type=2)
240
+
241
+ # Repeated measures with sphericity correction
242
+ result = anova_rm(y, subject=subj, within={'condition': cond}, correction='auto')
243
+ print(result.sphericity[0].gg_epsilon) # Greenhouse-Geisser correction
244
+
245
+ # Levene's test for homogeneity of variances
246
+ lev = levene_test(y, group, center='median') # Brown-Forsythe variant
247
+ print(lev.f_value, lev.p_value)
248
+
249
+ # --- Mixed models ---
250
+ from pystatistics.mixed import lmm, glmm
251
+
252
+ # Random intercept model (matches R lme4::lmer + lmerTest)
253
+ result = lmm(y, X, groups={'subject': subject_ids})
254
+ print(result.summary()) # lmerTest-style output with Satterthwaite df
255
+ print(result.icc) # intraclass correlation coefficient
256
+ print(result.ranef['subject']) # BLUPs (conditional modes) per subject
257
+
258
+ # Random intercept + slope
259
+ result = lmm(y, X, groups={'subject': subject_ids},
260
+ random_effects={'subject': ['1', 'time']},
261
+ random_data={'time': time_array})
262
+
263
+ # Crossed random effects (subjects x items)
264
+ result = lmm(y, X, groups={'subject': subj_ids, 'item': item_ids})
265
+
266
+ # Model comparison via LRT (requires ML, not REML)
267
+ m1 = lmm(y, X_reduced, groups={'subject': subj_ids}, reml=False)
268
+ m2 = lmm(y, X_full, groups={'subject': subj_ids}, reml=False)
269
+ print(m1.compare(m2)) # LRT chi-squared, df, p-value
270
+
271
+ # GLMM — logistic with random intercept
272
+ result = glmm(y_binary, X, groups={'subject': subject_ids},
273
+ family='binomial')
274
+ print(result.summary())
275
+
276
+ # GLMM — Poisson with random intercept
277
+ result = glmm(y_count, X, groups={'subject': subject_ids},
278
+ family='poisson')
279
+ ```
280
+
281
+ ## Modules
282
+
283
+ | Module | Status | Description |
284
+ |--------|--------|-------------|
285
+ | `regression/` LM | Complete | Linear models (OLS) with CPU QR and GPU Cholesky |
286
+ | `regression/` GLM | Complete | Generalized linear models (Gaussian, Binomial, Poisson) via IRLS |
287
+ | `mvnmle/` | Complete | Multivariate normal MLE with missing data (Direct + EM) |
288
+ | `descriptive/` | Complete | Descriptive statistics, correlation, quantiles, skewness, kurtosis |
289
+ | `hypothesis/` | Complete | t-test, chi-squared, Fisher exact, Wilcoxon, KS, proportions, F-test, p.adjust |
290
+ | `montecarlo/` | Complete | Bootstrap (ordinary, balanced, parametric), permutation tests, 5 CI methods, batched GPU solver |
291
+ | `survival/` | Complete | Survival analysis: Kaplan-Meier, log-rank test, Cox PH (CPU), discrete-time (GPU) |
292
+ | `anova/` | Complete | ANOVA: one-way, factorial, ANCOVA, repeated measures, Type I/II/III SS, Tukey/Bonferroni/Dunnett, Levene's test |
293
+ | `mixed/` LMM/GLMM | Complete | Linear and generalized linear mixed models (random intercepts/slopes, nested/crossed, REML/ML, Satterthwaite df, GLMM Laplace) |
294
+
295
+ See [docs/ROADMAP.md](docs/ROADMAP.md) for detailed scope, GPU applicability, and implementation priority for each module.
296
+
297
+ ## Architecture
298
+
299
+ Every module follows the same pattern:
300
+
301
+ ```
302
+ DataSource -> Design -> fit() -> Backend.solve() -> Result[Params] -> Solution
303
+ ```
304
+
305
+ - **CPU backends** are the gold standard, validated against R to rtol = 1e-10.
306
+ - **GPU backends** are validated against CPU backends per the tolerances above.
307
+ - **Two-tier validation** ensures correctness at any scale: Python-CPU vs R, then Python-GPU vs Python-CPU.
308
+
309
+ ## Installation
310
+
311
+ ```bash
312
+ pip install pystatistics
313
+
314
+ # With GPU support (requires PyTorch)
315
+ pip install pystatistics[gpu]
316
+
317
+ # Development
318
+ pip install pystatistics[dev]
319
+ ```
320
+
321
+ ## License
322
+
323
+ MIT
324
+
325
+ ## Author
326
+
327
+ Hai-Shuo (contact@sgcx.org)