epistasis-v2 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 (34) hide show
  1. epistasis_v2-1.0.0/Cargo.lock +323 -0
  2. epistasis_v2-1.0.0/Cargo.toml +13 -0
  3. epistasis_v2-1.0.0/PKG-INFO +119 -0
  4. epistasis_v2-1.0.0/README.md +86 -0
  5. epistasis_v2-1.0.0/crates/epistasis-core/Cargo.toml +16 -0
  6. epistasis_v2-1.0.0/crates/epistasis-core/src/lib.rs +20 -0
  7. epistasis_v2-1.0.0/pyproject.toml +123 -0
  8. epistasis_v2-1.0.0/python/epistasis/__init__.py +5 -0
  9. epistasis_v2-1.0.0/python/epistasis/_core.pyi +3 -0
  10. epistasis_v2-1.0.0/python/epistasis/_version.py +1 -0
  11. epistasis_v2-1.0.0/python/epistasis/exceptions.py +18 -0
  12. epistasis_v2-1.0.0/python/epistasis/mapping.py +251 -0
  13. epistasis_v2-1.0.0/python/epistasis/matrix.py +146 -0
  14. epistasis_v2-1.0.0/python/epistasis/models/__init__.py +5 -0
  15. epistasis_v2-1.0.0/python/epistasis/models/base.py +224 -0
  16. epistasis_v2-1.0.0/python/epistasis/models/classifiers/__init__.py +5 -0
  17. epistasis_v2-1.0.0/python/epistasis/models/classifiers/_base.py +124 -0
  18. epistasis_v2-1.0.0/python/epistasis/models/classifiers/logistic.py +100 -0
  19. epistasis_v2-1.0.0/python/epistasis/models/linear/__init__.py +13 -0
  20. epistasis_v2-1.0.0/python/epistasis/models/linear/_regularized.py +85 -0
  21. epistasis_v2-1.0.0/python/epistasis/models/linear/elastic_net.py +79 -0
  22. epistasis_v2-1.0.0/python/epistasis/models/linear/lasso.py +77 -0
  23. epistasis_v2-1.0.0/python/epistasis/models/linear/ordinary.py +126 -0
  24. epistasis_v2-1.0.0/python/epistasis/models/linear/ridge.py +60 -0
  25. epistasis_v2-1.0.0/python/epistasis/models/nonlinear/__init__.py +10 -0
  26. epistasis_v2-1.0.0/python/epistasis/models/nonlinear/minimizer.py +112 -0
  27. epistasis_v2-1.0.0/python/epistasis/models/nonlinear/ordinary.py +190 -0
  28. epistasis_v2-1.0.0/python/epistasis/sampling/__init__.py +5 -0
  29. epistasis_v2-1.0.0/python/epistasis/sampling/bayesian.py +115 -0
  30. epistasis_v2-1.0.0/python/epistasis/simulate/__init__.py +5 -0
  31. epistasis_v2-1.0.0/python/epistasis/simulate/linear.py +137 -0
  32. epistasis_v2-1.0.0/python/epistasis/stats.py +119 -0
  33. epistasis_v2-1.0.0/python/epistasis/utils.py +35 -0
  34. epistasis_v2-1.0.0/python/epistasis/validate.py +89 -0
@@ -0,0 +1,323 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
+
11
+ [[package]]
12
+ name = "cfg-if"
13
+ version = "1.0.4"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
16
+
17
+ [[package]]
18
+ name = "crossbeam-deque"
19
+ version = "0.8.6"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
22
+ dependencies = [
23
+ "crossbeam-epoch",
24
+ "crossbeam-utils",
25
+ ]
26
+
27
+ [[package]]
28
+ name = "crossbeam-epoch"
29
+ version = "0.9.18"
30
+ source = "registry+https://github.com/rust-lang/crates.io-index"
31
+ checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
32
+ dependencies = [
33
+ "crossbeam-utils",
34
+ ]
35
+
36
+ [[package]]
37
+ name = "crossbeam-utils"
38
+ version = "0.8.21"
39
+ source = "registry+https://github.com/rust-lang/crates.io-index"
40
+ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
41
+
42
+ [[package]]
43
+ name = "either"
44
+ version = "1.15.0"
45
+ source = "registry+https://github.com/rust-lang/crates.io-index"
46
+ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
47
+
48
+ [[package]]
49
+ name = "epistasis-core"
50
+ version = "0.1.0"
51
+ dependencies = [
52
+ "ndarray",
53
+ "numpy",
54
+ "pyo3",
55
+ "rayon",
56
+ ]
57
+
58
+ [[package]]
59
+ name = "heck"
60
+ version = "0.5.0"
61
+ source = "registry+https://github.com/rust-lang/crates.io-index"
62
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
63
+
64
+ [[package]]
65
+ name = "indoc"
66
+ version = "2.0.7"
67
+ source = "registry+https://github.com/rust-lang/crates.io-index"
68
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
69
+ dependencies = [
70
+ "rustversion",
71
+ ]
72
+
73
+ [[package]]
74
+ name = "libc"
75
+ version = "0.2.185"
76
+ source = "registry+https://github.com/rust-lang/crates.io-index"
77
+ checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
78
+
79
+ [[package]]
80
+ name = "matrixmultiply"
81
+ version = "0.3.10"
82
+ source = "registry+https://github.com/rust-lang/crates.io-index"
83
+ checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
84
+ dependencies = [
85
+ "autocfg",
86
+ "rawpointer",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "memoffset"
91
+ version = "0.9.1"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
94
+ dependencies = [
95
+ "autocfg",
96
+ ]
97
+
98
+ [[package]]
99
+ name = "ndarray"
100
+ version = "0.16.1"
101
+ source = "registry+https://github.com/rust-lang/crates.io-index"
102
+ checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841"
103
+ dependencies = [
104
+ "matrixmultiply",
105
+ "num-complex",
106
+ "num-integer",
107
+ "num-traits",
108
+ "portable-atomic",
109
+ "portable-atomic-util",
110
+ "rawpointer",
111
+ "rayon",
112
+ ]
113
+
114
+ [[package]]
115
+ name = "num-complex"
116
+ version = "0.4.6"
117
+ source = "registry+https://github.com/rust-lang/crates.io-index"
118
+ checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
119
+ dependencies = [
120
+ "num-traits",
121
+ ]
122
+
123
+ [[package]]
124
+ name = "num-integer"
125
+ version = "0.1.46"
126
+ source = "registry+https://github.com/rust-lang/crates.io-index"
127
+ checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
128
+ dependencies = [
129
+ "num-traits",
130
+ ]
131
+
132
+ [[package]]
133
+ name = "num-traits"
134
+ version = "0.2.19"
135
+ source = "registry+https://github.com/rust-lang/crates.io-index"
136
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
137
+ dependencies = [
138
+ "autocfg",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "numpy"
143
+ version = "0.23.0"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "b94caae805f998a07d33af06e6a3891e38556051b8045c615470a71590e13e78"
146
+ dependencies = [
147
+ "libc",
148
+ "ndarray",
149
+ "num-complex",
150
+ "num-integer",
151
+ "num-traits",
152
+ "pyo3",
153
+ "rustc-hash",
154
+ ]
155
+
156
+ [[package]]
157
+ name = "once_cell"
158
+ version = "1.21.4"
159
+ source = "registry+https://github.com/rust-lang/crates.io-index"
160
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
161
+
162
+ [[package]]
163
+ name = "portable-atomic"
164
+ version = "1.13.1"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
167
+
168
+ [[package]]
169
+ name = "portable-atomic-util"
170
+ version = "0.2.7"
171
+ source = "registry+https://github.com/rust-lang/crates.io-index"
172
+ checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618"
173
+ dependencies = [
174
+ "portable-atomic",
175
+ ]
176
+
177
+ [[package]]
178
+ name = "proc-macro2"
179
+ version = "1.0.106"
180
+ source = "registry+https://github.com/rust-lang/crates.io-index"
181
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
182
+ dependencies = [
183
+ "unicode-ident",
184
+ ]
185
+
186
+ [[package]]
187
+ name = "pyo3"
188
+ version = "0.23.5"
189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
190
+ checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
191
+ dependencies = [
192
+ "cfg-if",
193
+ "indoc",
194
+ "libc",
195
+ "memoffset",
196
+ "once_cell",
197
+ "portable-atomic",
198
+ "pyo3-build-config",
199
+ "pyo3-ffi",
200
+ "pyo3-macros",
201
+ "unindent",
202
+ ]
203
+
204
+ [[package]]
205
+ name = "pyo3-build-config"
206
+ version = "0.23.5"
207
+ source = "registry+https://github.com/rust-lang/crates.io-index"
208
+ checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
209
+ dependencies = [
210
+ "once_cell",
211
+ "target-lexicon",
212
+ ]
213
+
214
+ [[package]]
215
+ name = "pyo3-ffi"
216
+ version = "0.23.5"
217
+ source = "registry+https://github.com/rust-lang/crates.io-index"
218
+ checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
219
+ dependencies = [
220
+ "libc",
221
+ "pyo3-build-config",
222
+ ]
223
+
224
+ [[package]]
225
+ name = "pyo3-macros"
226
+ version = "0.23.5"
227
+ source = "registry+https://github.com/rust-lang/crates.io-index"
228
+ checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
229
+ dependencies = [
230
+ "proc-macro2",
231
+ "pyo3-macros-backend",
232
+ "quote",
233
+ "syn",
234
+ ]
235
+
236
+ [[package]]
237
+ name = "pyo3-macros-backend"
238
+ version = "0.23.5"
239
+ source = "registry+https://github.com/rust-lang/crates.io-index"
240
+ checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
241
+ dependencies = [
242
+ "heck",
243
+ "proc-macro2",
244
+ "pyo3-build-config",
245
+ "quote",
246
+ "syn",
247
+ ]
248
+
249
+ [[package]]
250
+ name = "quote"
251
+ version = "1.0.45"
252
+ source = "registry+https://github.com/rust-lang/crates.io-index"
253
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
254
+ dependencies = [
255
+ "proc-macro2",
256
+ ]
257
+
258
+ [[package]]
259
+ name = "rawpointer"
260
+ version = "0.2.1"
261
+ source = "registry+https://github.com/rust-lang/crates.io-index"
262
+ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
263
+
264
+ [[package]]
265
+ name = "rayon"
266
+ version = "1.12.0"
267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
268
+ checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
269
+ dependencies = [
270
+ "either",
271
+ "rayon-core",
272
+ ]
273
+
274
+ [[package]]
275
+ name = "rayon-core"
276
+ version = "1.13.0"
277
+ source = "registry+https://github.com/rust-lang/crates.io-index"
278
+ checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
279
+ dependencies = [
280
+ "crossbeam-deque",
281
+ "crossbeam-utils",
282
+ ]
283
+
284
+ [[package]]
285
+ name = "rustc-hash"
286
+ version = "2.1.2"
287
+ source = "registry+https://github.com/rust-lang/crates.io-index"
288
+ checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
289
+
290
+ [[package]]
291
+ name = "rustversion"
292
+ version = "1.0.22"
293
+ source = "registry+https://github.com/rust-lang/crates.io-index"
294
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
295
+
296
+ [[package]]
297
+ name = "syn"
298
+ version = "2.0.117"
299
+ source = "registry+https://github.com/rust-lang/crates.io-index"
300
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
301
+ dependencies = [
302
+ "proc-macro2",
303
+ "quote",
304
+ "unicode-ident",
305
+ ]
306
+
307
+ [[package]]
308
+ name = "target-lexicon"
309
+ version = "0.12.16"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
312
+
313
+ [[package]]
314
+ name = "unicode-ident"
315
+ version = "1.0.24"
316
+ source = "registry+https://github.com/rust-lang/crates.io-index"
317
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
318
+
319
+ [[package]]
320
+ name = "unindent"
321
+ version = "0.2.4"
322
+ source = "registry+https://github.com/rust-lang/crates.io-index"
323
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,13 @@
1
+ [workspace]
2
+ members = ["crates/epistasis-core"]
3
+ resolver = "2"
4
+
5
+ [workspace.package]
6
+ version = "0.1.0"
7
+ edition = "2021"
8
+ license = "Unlicense"
9
+ repository = "https://github.com/lperezmo/epistasis-v2"
10
+
11
+ [profile.release]
12
+ lto = "thin"
13
+ codegen-units = 1
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.4
2
+ Name: epistasis-v2
3
+ Version: 1.0.0
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Science/Research
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.10
8
+ Classifier: Programming Language :: Python :: 3.11
9
+ Classifier: Programming Language :: Python :: 3.12
10
+ Classifier: Programming Language :: Python :: 3.13
11
+ Classifier: Programming Language :: Rust
12
+ Classifier: License :: Public Domain
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
15
+ Requires-Dist: numpy>=1.23
16
+ Requires-Dist: pandas>=2.0
17
+ Requires-Dist: scipy>=1.11
18
+ Requires-Dist: scikit-learn>=1.3
19
+ Requires-Dist: lmfit>=1.2
20
+ Requires-Dist: emcee>=3.1
21
+ Requires-Dist: matplotlib>=3.7
22
+ Requires-Dist: gpmap-v2>=1.0.0
23
+ Summary: High-performance Python library for fitting high-order epistatic interactions in genotype-phenotype maps.
24
+ Keywords: epistasis,genotype-phenotype,genetics,genomics,bioinformatics
25
+ Author-email: Luis Perez <lperezmo@users.noreply.github.com>
26
+ License: Unlicense
27
+ Requires-Python: >=3.10
28
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
29
+ Project-URL: Homepage, https://github.com/lperezmo/epistasis-v2
30
+ Project-URL: Issues, https://github.com/lperezmo/epistasis-v2/issues
31
+ Project-URL: Repository, https://github.com/lperezmo/epistasis-v2
32
+
33
+ # epistasis-v2
34
+
35
+ High-performance Python library for fitting high-order epistatic interactions in genotype-phenotype maps. A clean-break rewrite of [harmslab/epistasis](https://github.com/harmslab/epistasis).
36
+
37
+ **Status: alpha.** Phase 1 port complete; Phase 2 Rust kernel and Phase 3 FWHT / sparse paths still to come.
38
+
39
+ ## What changed from v1
40
+
41
+ - Rust hot-path kernels via PyO3 (`epistasis._core`) instead of a shipped Cython `.c` blob.
42
+ - `uv` + `maturin` build. `pyproject.toml` only; no `setup.py`.
43
+ - Python 3.10 through 3.13. Older interpreters dropped.
44
+ - Type hints on the public API; `mypy --strict` in CI.
45
+ - Composition over `@use_sklearn` MRO injection. Concrete models hold an sklearn estimator as an attribute and forward calls explicitly, which unlocks modern sklearn (>=1.2) that broke the v1 trick when `normalize=` was removed.
46
+ - Walsh-Hadamard fast-path for Hadamard-encoded OLS fits (Phase 3, not yet landed).
47
+ - Sparse design matrix path for Lasso / ElasticNet at high order (Phase 3).
48
+ - Coordinated rewrite of the [gpmap](https://github.com/harmslab/gpmap) dependency as [gpmap-v2](https://github.com/lperezmo/gpmap-v2). Consumes `binary_packed` (uint8 2D) and `encoding_table` with `site_index` instead of the deprecated `genotype_index`.
49
+ - No backward compatibility with v1. Pin the v1 package if you need that behavior.
50
+
51
+ ## Repository layout
52
+
53
+ ```
54
+ epistasis-v2/
55
+ ├── pyproject.toml uv + maturin build, ruff + mypy + pytest config
56
+ ├── Cargo.toml Rust workspace
57
+ ├── python/epistasis/ Python source (installed as `epistasis`)
58
+ ├── crates/epistasis-core/ Rust crate, exposed as `epistasis._core`
59
+ ├── tests/ pytest suite
60
+ ├── benches/ pytest-benchmark + criterion (Phase 2+)
61
+ ├── docs/ Sphinx docs (Phase 5)
62
+ ├── .github/workflows/ CI (lint, test, matrix) + release (semantic-release, maturin wheels, PyPI OIDC)
63
+ ├── CHANGELOG.md generated by python-semantic-release
64
+ └── CONTRIBUTING.md commit conventions, dev workflow
65
+ ```
66
+
67
+ ## Installation (dev)
68
+
69
+ Requires Python >= 3.10 and a Rust toolchain. `gpmap-v2` is pulled from PyPI.
70
+
71
+ ```bash
72
+ uv sync
73
+ uv run maturin develop --release
74
+ uv run pytest
75
+ ```
76
+
77
+ For lint and type-check:
78
+
79
+ ```bash
80
+ uv run ruff check .
81
+ uv run ruff format --check .
82
+ uv run mypy python/epistasis
83
+ ```
84
+
85
+ ## Current progress
86
+
87
+ Phase 0 (scaffold) and Phase 1 (port) complete.
88
+
89
+ Ported modules:
90
+
91
+ - `epistasis.mapping` (sites, coefficients, `EpistasisMap`)
92
+ - `epistasis.matrix` (encoded vectors, design matrix, NumPy backend)
93
+ - `epistasis.exceptions` (`EpistasisError`, `XMatrixError`, `FittingError`)
94
+ - `epistasis.utils` (`genotypes_to_X`)
95
+ - `epistasis.models.base` (`AbstractEpistasisModel`, `EpistasisBaseModel`)
96
+ - `epistasis.models.linear` (`EpistasisLinearRegression` with analytic coefficient standard errors, `EpistasisRidge`, `EpistasisLasso`, `EpistasisElasticNet`)
97
+ - `epistasis.models.nonlinear` (`EpistasisNonlinearRegression`, `FunctionMinimizer`; `power` and `spline` variants deferred)
98
+ - `epistasis.models.classifiers` (`EpistasisLogisticRegression`; LDA, QDA, Gaussian Process, and GMM deferred)
99
+ - `epistasis.simulate` (`simulate_linear_gpm`, `simulate_random_linear_gpm`)
100
+ - `epistasis.stats` (Pearson, R^2, RMSD, SS residuals, AIC, `split_gpm`)
101
+ - `epistasis.validate` (`k_fold`, `holdout`)
102
+ - `epistasis.sampling.bayesian` (`BayesianSampler` via emcee 3)
103
+
104
+ Pending:
105
+
106
+ - Rust kernels for `build_model_matrix`, `encode_vectors`, FWHT fast path (Phase 2)
107
+ - Sparse design matrix path for Lasso / ElasticNet (Phase 3)
108
+ - `power.py` and `spline.py` nonlinear variants
109
+ - Remaining classifier implementations if demand surfaces
110
+ - ReadTheDocs build
111
+
112
+ ## Contributing
113
+
114
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Commits follow [Conventional Commits](https://www.conventionalcommits.org/); releases and the changelog are automated by `python-semantic-release`.
115
+
116
+ ## License
117
+
118
+ Unlicense (public domain). See [UNLICENSE](UNLICENSE).
119
+
@@ -0,0 +1,86 @@
1
+ # epistasis-v2
2
+
3
+ High-performance Python library for fitting high-order epistatic interactions in genotype-phenotype maps. A clean-break rewrite of [harmslab/epistasis](https://github.com/harmslab/epistasis).
4
+
5
+ **Status: alpha.** Phase 1 port complete; Phase 2 Rust kernel and Phase 3 FWHT / sparse paths still to come.
6
+
7
+ ## What changed from v1
8
+
9
+ - Rust hot-path kernels via PyO3 (`epistasis._core`) instead of a shipped Cython `.c` blob.
10
+ - `uv` + `maturin` build. `pyproject.toml` only; no `setup.py`.
11
+ - Python 3.10 through 3.13. Older interpreters dropped.
12
+ - Type hints on the public API; `mypy --strict` in CI.
13
+ - Composition over `@use_sklearn` MRO injection. Concrete models hold an sklearn estimator as an attribute and forward calls explicitly, which unlocks modern sklearn (>=1.2) that broke the v1 trick when `normalize=` was removed.
14
+ - Walsh-Hadamard fast-path for Hadamard-encoded OLS fits (Phase 3, not yet landed).
15
+ - Sparse design matrix path for Lasso / ElasticNet at high order (Phase 3).
16
+ - Coordinated rewrite of the [gpmap](https://github.com/harmslab/gpmap) dependency as [gpmap-v2](https://github.com/lperezmo/gpmap-v2). Consumes `binary_packed` (uint8 2D) and `encoding_table` with `site_index` instead of the deprecated `genotype_index`.
17
+ - No backward compatibility with v1. Pin the v1 package if you need that behavior.
18
+
19
+ ## Repository layout
20
+
21
+ ```
22
+ epistasis-v2/
23
+ ├── pyproject.toml uv + maturin build, ruff + mypy + pytest config
24
+ ├── Cargo.toml Rust workspace
25
+ ├── python/epistasis/ Python source (installed as `epistasis`)
26
+ ├── crates/epistasis-core/ Rust crate, exposed as `epistasis._core`
27
+ ├── tests/ pytest suite
28
+ ├── benches/ pytest-benchmark + criterion (Phase 2+)
29
+ ├── docs/ Sphinx docs (Phase 5)
30
+ ├── .github/workflows/ CI (lint, test, matrix) + release (semantic-release, maturin wheels, PyPI OIDC)
31
+ ├── CHANGELOG.md generated by python-semantic-release
32
+ └── CONTRIBUTING.md commit conventions, dev workflow
33
+ ```
34
+
35
+ ## Installation (dev)
36
+
37
+ Requires Python >= 3.10 and a Rust toolchain. `gpmap-v2` is pulled from PyPI.
38
+
39
+ ```bash
40
+ uv sync
41
+ uv run maturin develop --release
42
+ uv run pytest
43
+ ```
44
+
45
+ For lint and type-check:
46
+
47
+ ```bash
48
+ uv run ruff check .
49
+ uv run ruff format --check .
50
+ uv run mypy python/epistasis
51
+ ```
52
+
53
+ ## Current progress
54
+
55
+ Phase 0 (scaffold) and Phase 1 (port) complete.
56
+
57
+ Ported modules:
58
+
59
+ - `epistasis.mapping` (sites, coefficients, `EpistasisMap`)
60
+ - `epistasis.matrix` (encoded vectors, design matrix, NumPy backend)
61
+ - `epistasis.exceptions` (`EpistasisError`, `XMatrixError`, `FittingError`)
62
+ - `epistasis.utils` (`genotypes_to_X`)
63
+ - `epistasis.models.base` (`AbstractEpistasisModel`, `EpistasisBaseModel`)
64
+ - `epistasis.models.linear` (`EpistasisLinearRegression` with analytic coefficient standard errors, `EpistasisRidge`, `EpistasisLasso`, `EpistasisElasticNet`)
65
+ - `epistasis.models.nonlinear` (`EpistasisNonlinearRegression`, `FunctionMinimizer`; `power` and `spline` variants deferred)
66
+ - `epistasis.models.classifiers` (`EpistasisLogisticRegression`; LDA, QDA, Gaussian Process, and GMM deferred)
67
+ - `epistasis.simulate` (`simulate_linear_gpm`, `simulate_random_linear_gpm`)
68
+ - `epistasis.stats` (Pearson, R^2, RMSD, SS residuals, AIC, `split_gpm`)
69
+ - `epistasis.validate` (`k_fold`, `holdout`)
70
+ - `epistasis.sampling.bayesian` (`BayesianSampler` via emcee 3)
71
+
72
+ Pending:
73
+
74
+ - Rust kernels for `build_model_matrix`, `encode_vectors`, FWHT fast path (Phase 2)
75
+ - Sparse design matrix path for Lasso / ElasticNet (Phase 3)
76
+ - `power.py` and `spline.py` nonlinear variants
77
+ - Remaining classifier implementations if demand surfaces
78
+ - ReadTheDocs build
79
+
80
+ ## Contributing
81
+
82
+ See [CONTRIBUTING.md](CONTRIBUTING.md). Commits follow [Conventional Commits](https://www.conventionalcommits.org/); releases and the changelog are automated by `python-semantic-release`.
83
+
84
+ ## License
85
+
86
+ Unlicense (public domain). See [UNLICENSE](UNLICENSE).
@@ -0,0 +1,16 @@
1
+ [package]
2
+ name = "epistasis-core"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ repository.workspace = true
7
+
8
+ [lib]
9
+ name = "epistasis_core"
10
+ crate-type = ["cdylib"]
11
+
12
+ [dependencies]
13
+ pyo3 = { version = "0.23", features = ["extension-module", "abi3-py310"] }
14
+ numpy = "0.23"
15
+ ndarray = { version = "0.16", features = ["rayon"] }
16
+ rayon = "1.10"
@@ -0,0 +1,20 @@
1
+ //! epistasis-core: Rust hot-path kernels for epistasis-v2.
2
+ //!
3
+ //! This crate is exposed to Python as `epistasis._core` via PyO3.
4
+ //! Phase 0 scaffold: no kernels implemented yet. Phase 2 adds
5
+ //! `build_model_matrix`, `encode_vectors`, and the Walsh-Hadamard
6
+ //! transform fast path.
7
+
8
+ use pyo3::prelude::*;
9
+
10
+ /// Returns the crate version. Smoke test for the Python-Rust bridge.
11
+ #[pyfunction]
12
+ fn version() -> &'static str {
13
+ env!("CARGO_PKG_VERSION")
14
+ }
15
+
16
+ #[pymodule]
17
+ fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
18
+ m.add_function(wrap_pyfunction!(version, m)?)?;
19
+ Ok(())
20
+ }