statgpu 0.1.0__py3-none-any.whl

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 (168) hide show
  1. statgpu/__init__.py +174 -0
  2. statgpu/_base.py +544 -0
  3. statgpu/_config.py +127 -0
  4. statgpu/anova/__init__.py +5 -0
  5. statgpu/anova/_oneway.py +194 -0
  6. statgpu/backends/__init__.py +83 -0
  7. statgpu/backends/_array_ops.py +529 -0
  8. statgpu/backends/_base.py +184 -0
  9. statgpu/backends/_cupy.py +453 -0
  10. statgpu/backends/_factory.py +65 -0
  11. statgpu/backends/_gpu_inference_cupy.py +214 -0
  12. statgpu/backends/_gpu_inference_torch.py +422 -0
  13. statgpu/backends/_numpy.py +324 -0
  14. statgpu/backends/_torch.py +685 -0
  15. statgpu/backends/_torch_safe.py +47 -0
  16. statgpu/backends/_utils.py +423 -0
  17. statgpu/core/__init__.py +10 -0
  18. statgpu/core/formula/__init__.py +33 -0
  19. statgpu/core/formula/_design.py +99 -0
  20. statgpu/core/formula/_parser.py +191 -0
  21. statgpu/core/formula/_terms.py +70 -0
  22. statgpu/core/formula/tests/__init__.py +0 -0
  23. statgpu/core/formula/tests/test_parser.py +194 -0
  24. statgpu/covariance/__init__.py +6 -0
  25. statgpu/covariance/_empirical.py +310 -0
  26. statgpu/covariance/_shrinkage.py +248 -0
  27. statgpu/cross_validation/__init__.py +31 -0
  28. statgpu/cross_validation/_base.py +410 -0
  29. statgpu/cross_validation/_engine.py +167 -0
  30. statgpu/diagnostics/__init__.py +7 -0
  31. statgpu/diagnostics/_regression_diagnostics.py +188 -0
  32. statgpu/feature_selection/__init__.py +24 -0
  33. statgpu/feature_selection/_knockoff.py +870 -0
  34. statgpu/feature_selection/_knockoff_utils.py +1003 -0
  35. statgpu/feature_selection/_stepwise.py +300 -0
  36. statgpu/glm_core/__init__.py +81 -0
  37. statgpu/glm_core/_base.py +202 -0
  38. statgpu/glm_core/_family.py +362 -0
  39. statgpu/glm_core/_fused.py +149 -0
  40. statgpu/glm_core/_gamma.py +111 -0
  41. statgpu/glm_core/_inverse_gaussian.py +62 -0
  42. statgpu/glm_core/_irls.py +561 -0
  43. statgpu/glm_core/_logistic.py +82 -0
  44. statgpu/glm_core/_negative_binomial.py +68 -0
  45. statgpu/glm_core/_poisson.py +60 -0
  46. statgpu/glm_core/_solver_legacy.py +100 -0
  47. statgpu/glm_core/_squared.py +53 -0
  48. statgpu/glm_core/_tweedie.py +74 -0
  49. statgpu/inference/__init__.py +239 -0
  50. statgpu/inference/_distributions_backend.py +2610 -0
  51. statgpu/inference/_multiple_testing.py +391 -0
  52. statgpu/inference/_resampling.py +1400 -0
  53. statgpu/inference/_results.py +265 -0
  54. statgpu/linear_model/__init__.py +75 -0
  55. statgpu/linear_model/_gaussian_inference.py +306 -0
  56. statgpu/linear_model/_glm_base.py +1261 -0
  57. statgpu/linear_model/_ordered_logit.py +52 -0
  58. statgpu/linear_model/_ordered_probit.py +50 -0
  59. statgpu/linear_model/_stats.py +170 -0
  60. statgpu/linear_model/cv/__init__.py +13 -0
  61. statgpu/linear_model/cv/_elasticnet_cv.py +892 -0
  62. statgpu/linear_model/cv/_lasso_cv.py +253 -0
  63. statgpu/linear_model/cv/_logistic_cv.py +895 -0
  64. statgpu/linear_model/cv/_ridge_cv.py +1160 -0
  65. statgpu/linear_model/legacy/__init__.py +1 -0
  66. statgpu/linear_model/legacy/_distributions_legacy_gpu.py +340 -0
  67. statgpu/linear_model/legacy/_elasticnet_legacy.py +936 -0
  68. statgpu/linear_model/legacy/_lasso_legacy.py +4876 -0
  69. statgpu/linear_model/legacy/_penalized_legacy.py +1174 -0
  70. statgpu/linear_model/legacy/_ridge_legacy.py +863 -0
  71. statgpu/linear_model/legacy/_solver_legacy.py +104 -0
  72. statgpu/linear_model/penalized/__init__.py +25 -0
  73. statgpu/linear_model/penalized/_base.py +437 -0
  74. statgpu/linear_model/penalized/_fit_mixin.py +1877 -0
  75. statgpu/linear_model/penalized/_inference_mixin.py +1179 -0
  76. statgpu/linear_model/penalized/_penalized_cv.py +2699 -0
  77. statgpu/linear_model/penalized/_penalized_gamma.py +86 -0
  78. statgpu/linear_model/penalized/_penalized_inverse_gaussian.py +62 -0
  79. statgpu/linear_model/penalized/_penalized_linear.py +236 -0
  80. statgpu/linear_model/penalized/_penalized_logistic.py +100 -0
  81. statgpu/linear_model/penalized/_penalized_negative_binomial.py +65 -0
  82. statgpu/linear_model/penalized/_penalized_poisson.py +62 -0
  83. statgpu/linear_model/penalized/_penalized_tweedie.py +65 -0
  84. statgpu/linear_model/penalized/_predict_mixin.py +182 -0
  85. statgpu/linear_model/wrappers/__init__.py +31 -0
  86. statgpu/linear_model/wrappers/_adaptive_lasso.py +63 -0
  87. statgpu/linear_model/wrappers/_elasticnet.py +75 -0
  88. statgpu/linear_model/wrappers/_gamma.py +67 -0
  89. statgpu/linear_model/wrappers/_inverse_gaussian.py +47 -0
  90. statgpu/linear_model/wrappers/_lasso.py +2124 -0
  91. statgpu/linear_model/wrappers/_linear.py +1127 -0
  92. statgpu/linear_model/wrappers/_logistic.py +1435 -0
  93. statgpu/linear_model/wrappers/_mcp.py +58 -0
  94. statgpu/linear_model/wrappers/_negative_binomial.py +58 -0
  95. statgpu/linear_model/wrappers/_poisson.py +48 -0
  96. statgpu/linear_model/wrappers/_ridge.py +166 -0
  97. statgpu/linear_model/wrappers/_scad.py +58 -0
  98. statgpu/linear_model/wrappers/_tweedie.py +57 -0
  99. statgpu/metrics/__init__.py +21 -0
  100. statgpu/metrics/_classification.py +591 -0
  101. statgpu/nonparametric/__init__.py +50 -0
  102. statgpu/nonparametric/kernel_methods/__init__.py +25 -0
  103. statgpu/nonparametric/kernel_methods/_kernels.py +246 -0
  104. statgpu/nonparametric/kernel_methods/_krr.py +234 -0
  105. statgpu/nonparametric/kernel_methods/_krr_cv.py +380 -0
  106. statgpu/nonparametric/kernel_smoothing/__init__.py +39 -0
  107. statgpu/nonparametric/kernel_smoothing/_bandwidth_selection.py +1083 -0
  108. statgpu/nonparametric/kernel_smoothing/_kde.py +761 -0
  109. statgpu/nonparametric/kernel_smoothing/_kernel_common.py +348 -0
  110. statgpu/nonparametric/kernel_smoothing/_kernel_regression.py +748 -0
  111. statgpu/nonparametric/splines/__init__.py +5 -0
  112. statgpu/nonparametric/splines/_bspline_basis.py +336 -0
  113. statgpu/nonparametric/splines/_penalized.py +349 -0
  114. statgpu/panel/__init__.py +19 -0
  115. statgpu/panel/_covariance.py +140 -0
  116. statgpu/panel/_fixed_effects.py +420 -0
  117. statgpu/panel/_random_effects.py +385 -0
  118. statgpu/panel/_utils.py +482 -0
  119. statgpu/penalties/__init__.py +139 -0
  120. statgpu/penalties/_adaptive_l1.py +313 -0
  121. statgpu/penalties/_base.py +261 -0
  122. statgpu/penalties/_categories.py +39 -0
  123. statgpu/penalties/_elasticnet.py +98 -0
  124. statgpu/penalties/_group_lasso.py +678 -0
  125. statgpu/penalties/_group_mcp.py +553 -0
  126. statgpu/penalties/_group_scad.py +605 -0
  127. statgpu/penalties/_l1.py +107 -0
  128. statgpu/penalties/_l2.py +77 -0
  129. statgpu/penalties/_mcp.py +237 -0
  130. statgpu/penalties/_scad.py +260 -0
  131. statgpu/semiparametric/__init__.py +5 -0
  132. statgpu/semiparametric/_gam.py +401 -0
  133. statgpu/solvers/__init__.py +24 -0
  134. statgpu/solvers/_admm.py +241 -0
  135. statgpu/solvers/_constants.py +15 -0
  136. statgpu/solvers/_convergence.py +6 -0
  137. statgpu/solvers/_fista.py +436 -0
  138. statgpu/solvers/_fista_bb.py +513 -0
  139. statgpu/solvers/_fista_lla.py +541 -0
  140. statgpu/solvers/_lbfgs.py +206 -0
  141. statgpu/solvers/_newton.py +149 -0
  142. statgpu/solvers/_utils.py +277 -0
  143. statgpu/survival/__init__.py +14 -0
  144. statgpu/survival/_cox.py +3974 -0
  145. statgpu/survival/_cox_breslow_triton_kernel.py +106 -0
  146. statgpu/survival/_cox_cv.py +1159 -0
  147. statgpu/survival/_cox_efron_cuda.py +1280 -0
  148. statgpu/survival/_cox_efron_triton.py +359 -0
  149. statgpu/unsupervised/__init__.py +29 -0
  150. statgpu/unsupervised/_agglomerative.py +307 -0
  151. statgpu/unsupervised/_dbscan.py +263 -0
  152. statgpu/unsupervised/_dbscan_cpu.pyx +125 -0
  153. statgpu/unsupervised/_gmm.py +332 -0
  154. statgpu/unsupervised/_incremental_pca.py +176 -0
  155. statgpu/unsupervised/_kmeans.py +261 -0
  156. statgpu/unsupervised/_minibatch_kmeans.py +299 -0
  157. statgpu/unsupervised/_minibatch_nmf.py +252 -0
  158. statgpu/unsupervised/_nmf.py +190 -0
  159. statgpu/unsupervised/_pca.py +189 -0
  160. statgpu/unsupervised/_truncated_svd.py +132 -0
  161. statgpu/unsupervised/_tsne.py +192 -0
  162. statgpu/unsupervised/_umap.py +224 -0
  163. statgpu/unsupervised/_utils.py +134 -0
  164. statgpu-0.1.0.dist-info/METADATA +245 -0
  165. statgpu-0.1.0.dist-info/RECORD +168 -0
  166. statgpu-0.1.0.dist-info/WHEEL +5 -0
  167. statgpu-0.1.0.dist-info/licenses/LICENSE +199 -0
  168. statgpu-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,324 @@
1
+ """
2
+ NumPy / SciPy CPU backend.
3
+ """
4
+
5
+ import numpy as np
6
+
7
+ from statgpu.backends._base import BackendBase
8
+
9
+
10
+ class NumpyBackend(BackendBase):
11
+ """
12
+ CPU backend powered by NumPy.
13
+
14
+ This backend is always available and serves as the fallback when no GPU
15
+ library is installed.
16
+ """
17
+
18
+ name = "numpy"
19
+
20
+ @property
21
+ def xp(self):
22
+ return np
23
+
24
+ def asarray(self, x, dtype=None):
25
+ if hasattr(x, "get"):
26
+ # CuPy arrays expose a .get() method that transfers the array from
27
+ # GPU memory to a NumPy ndarray on the host. We use duck-typing
28
+ # here to avoid importing cupy when it may not be installed.
29
+ x = x.get()
30
+ elif hasattr(x, "cpu"):
31
+ # PyTorch tensors expose a .cpu() method that moves the tensor to
32
+ # CPU memory before converting to NumPy. Duck-typing avoids a
33
+ # mandatory torch import.
34
+ x = x.detach().cpu().numpy()
35
+ return np.asarray(x, dtype=dtype)
36
+
37
+ def to_numpy(self, x) -> np.ndarray:
38
+ return self.asarray(x)
39
+
40
+ def is_available(self) -> bool:
41
+ return True
42
+
43
+ def lstsq(self, A, b, rcond=None):
44
+ return np.linalg.lstsq(A, b, rcond=rcond)
45
+
46
+ # ------------------------------------------------------------------
47
+ # Helper methods for array operations (mirror CuPyBackend API)
48
+ # ------------------------------------------------------------------
49
+
50
+ def sum(self, x, axis=None, keepdims=False):
51
+ """Sum over specified axis/axes."""
52
+ return np.sum(x, axis=axis, keepdims=keepdims)
53
+
54
+ def mean(self, x, axis=None, keepdims=False):
55
+ """Mean over specified axis/axes."""
56
+ return np.mean(x, axis=axis, keepdims=keepdims)
57
+
58
+ def sqrt(self, x):
59
+ """Element-wise square root."""
60
+ return np.sqrt(x)
61
+
62
+ def abs(self, x):
63
+ """Element-wise absolute value."""
64
+ return np.abs(x)
65
+
66
+ def max(self, x, axis=None, keepdims=False):
67
+ """Maximum value along axis."""
68
+ return np.max(x, axis=axis, keepdims=keepdims)
69
+
70
+ def outer(self, a, b):
71
+ """Outer product."""
72
+ return np.outer(a.flatten(), b.flatten())
73
+
74
+ def stack(self, arrays, axis=0):
75
+ """Stack arrays along a new axis."""
76
+ return np.stack(arrays, axis=axis)
77
+
78
+ def zeros(self, shape, dtype=None):
79
+ """Create array of zeros."""
80
+ return np.zeros(shape, dtype=dtype)
81
+
82
+ def array(self, val, dtype=None):
83
+ """Create a scalar or array from a value."""
84
+ return np.array(val, dtype=dtype)
85
+
86
+ def arange(self, start, stop=None, step=1, dtype=None):
87
+ """Create range array."""
88
+ if stop is None:
89
+ result = np.arange(start, step=step)
90
+ else:
91
+ result = np.arange(start, stop, step=step)
92
+ if dtype is not None:
93
+ result = result.astype(dtype)
94
+ return result
95
+
96
+ def full(self, shape, fill_value, dtype=None):
97
+ """Create array filled with a constant value."""
98
+ return np.full(shape, fill_value, dtype=dtype)
99
+
100
+ def atleast_1d(self, x):
101
+ """Ensure array is at least 1D."""
102
+ return np.atleast_1d(x)
103
+
104
+ @property
105
+ def newaxis(self):
106
+ """Alias for None, used in indexing."""
107
+ return np.newaxis
108
+
109
+ @property
110
+ def float64(self):
111
+ """float64 dtype."""
112
+ return np.float64
113
+
114
+ @property
115
+ def float32(self):
116
+ """float32 dtype."""
117
+ return np.float32
118
+
119
+ @property
120
+ def int64(self):
121
+ """int64 dtype."""
122
+ return np.int64
123
+
124
+ @property
125
+ def int32(self):
126
+ """int32 dtype."""
127
+ return np.int32
128
+
129
+ def minimum(self, x, y):
130
+ """Element-wise minimum of two arrays."""
131
+ return np.minimum(x, y)
132
+
133
+ def maximum(self, x, y):
134
+ """Element-wise maximum of two arrays."""
135
+ return np.maximum(x, y)
136
+
137
+ def transpose(self, x, axes=None):
138
+ """Transpose array."""
139
+ return np.transpose(x, axes)
140
+
141
+ def clip(self, x, min_val, max_val):
142
+ """Clip values to [min_val, max_val]."""
143
+ return np.clip(x, min_val, max_val)
144
+
145
+ # ------------------------------------------------------------------
146
+ # Additional methods matching TorchBackend API
147
+ # ------------------------------------------------------------------
148
+
149
+ def matmul(self, a, b):
150
+ """Matrix multiplication."""
151
+ return np.matmul(a, b)
152
+
153
+ def svd(self, a, full_matrices=True):
154
+ """Singular value decomposition."""
155
+ return np.linalg.svd(a, full_matrices=full_matrices)
156
+
157
+ def eigh(self, a):
158
+ """Eigenvalue decomposition for symmetric/Hermitian matrices."""
159
+ return np.linalg.eigh(a)
160
+
161
+ def qr(self, a, mode='reduced'):
162
+ """QR decomposition."""
163
+ return np.linalg.qr(a, mode=mode)
164
+
165
+ def solve(self, a, b):
166
+ """Solve linear system Ax = b."""
167
+ return np.linalg.solve(a, b)
168
+
169
+ def solve_triangular(self, a, b, lower=True):
170
+ """Solve triangular system."""
171
+ from scipy.linalg import solve_triangular
172
+ return solve_triangular(a, b, lower=lower)
173
+
174
+ def expand_dims(self, x, axis):
175
+ """Expand array dimensions."""
176
+ return np.expand_dims(x, axis=axis)
177
+
178
+ def eye(self, n, dtype=None):
179
+ """Create identity matrix."""
180
+ return np.eye(n, dtype=dtype)
181
+
182
+ def argmin(self, x, axis=None):
183
+ """Return indices of minimum values."""
184
+ return np.argmin(x, axis=axis)
185
+
186
+ def argmax(self, x, axis=None):
187
+ """Return indices of maximum values."""
188
+ return np.argmax(x, axis=axis)
189
+
190
+ def argsort(self, x, axis=-1):
191
+ """Return indices that would sort the array."""
192
+ return np.argsort(x, axis=axis)
193
+
194
+ def diag(self, x):
195
+ """Extract diagonal or construct diagonal matrix."""
196
+ return np.diag(x)
197
+
198
+ def log(self, x):
199
+ """Element-wise natural logarithm."""
200
+ return np.log(x)
201
+
202
+ def log1p(self, x):
203
+ """Element-wise log(1 + x)."""
204
+ return np.log1p(x)
205
+
206
+ def exp(self, x):
207
+ """Element-wise exponential."""
208
+ return np.exp(x)
209
+
210
+ def square(self, x):
211
+ """Element-wise square."""
212
+ return np.square(x)
213
+
214
+ def sign(self, x):
215
+ """Element-wise sign."""
216
+ return np.sign(x)
217
+
218
+ def item(self, x):
219
+ """Extract scalar value from single-element array."""
220
+ return x.item()
221
+
222
+ def min(self, x, axis=None, keepdims=False):
223
+ """Minimum value along axis."""
224
+ return np.min(x, axis=axis, keepdims=keepdims)
225
+
226
+ def norm(self, x, ord=None, axis=None):
227
+ """Compute matrix or vector norm."""
228
+ return np.linalg.norm(x, ord=ord, axis=axis)
229
+
230
+ def ones(self, shape, dtype=None):
231
+ """Create array of ones."""
232
+ return np.ones(shape, dtype=dtype)
233
+
234
+ def ones_like(self, x):
235
+ """Create array of ones with same shape."""
236
+ return np.ones_like(x)
237
+
238
+ def zeros_like(self, x):
239
+ """Create array of zeros with same shape."""
240
+ return np.zeros_like(x)
241
+
242
+ def full_like(self, x, fill_value):
243
+ """Create array filled with value, same shape."""
244
+ return np.full_like(x, fill_value)
245
+
246
+ def where(self, condition, x, y):
247
+ """Element-wise conditional."""
248
+ return np.where(condition, x, y)
249
+
250
+ def any(self, x, axis=None):
251
+ """Test whether any element is True."""
252
+ return np.any(x, axis=axis)
253
+
254
+ def all(self, x, axis=None):
255
+ """Test whether all elements are True."""
256
+ return np.all(x, axis=axis)
257
+
258
+ def unique(self, x):
259
+ """Find unique elements."""
260
+ return np.unique(x)
261
+
262
+ def sort(self, x, axis=-1):
263
+ """Sort array along axis."""
264
+ return np.sort(x, axis=axis)
265
+
266
+ def isnan(self, x):
267
+ """Element-wise NaN check."""
268
+ return np.isnan(x)
269
+
270
+ def isinf(self, x):
271
+ """Element-wise Inf check."""
272
+ return np.isinf(x)
273
+
274
+ def nan_to_num(self, x):
275
+ """Replace NaN/Inf with numbers."""
276
+ return np.nan_to_num(x)
277
+
278
+ def count_nonzero(self, x):
279
+ """Count non-zero elements."""
280
+ return np.count_nonzero(x)
281
+
282
+ def einsum(self, subscripts, *operands):
283
+ """Einstein summation."""
284
+ return np.einsum(subscripts, *operands)
285
+
286
+ def tensordot(self, a, b, axes=2):
287
+ """Tensor dot product."""
288
+ return np.tensordot(a, b, axes=axes)
289
+
290
+ def meshgrid(self, *xi):
291
+ """Create N-D coordinate arrays."""
292
+ return np.meshgrid(*xi)
293
+
294
+ def squeeze(self, x, axis=None):
295
+ """Remove single-dimensional entries."""
296
+ return np.squeeze(x, axis=axis)
297
+
298
+ def flatten(self, x):
299
+ """Return flattened array."""
300
+ return x.flatten()
301
+
302
+ def empty_cache(self):
303
+ """No-op for CPU backend."""
304
+ pass
305
+
306
+ @property
307
+ def inf(self):
308
+ """Infinity value."""
309
+ return np.inf
310
+
311
+ @property
312
+ def nan(self):
313
+ """NaN value."""
314
+ return np.nan
315
+
316
+ @property
317
+ def pi(self):
318
+ """Pi constant."""
319
+ return np.pi
320
+
321
+ @property
322
+ def bool(self):
323
+ """Boolean dtype."""
324
+ return np.bool_