fpembed 0.1.6__tar.gz → 0.1.7__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 (27) hide show
  1. {fpembed-0.1.6/src/fpembed.egg-info → fpembed-0.1.7}/PKG-INFO +8 -8
  2. {fpembed-0.1.6 → fpembed-0.1.7}/README.md +7 -7
  3. {fpembed-0.1.6 → fpembed-0.1.7}/pyproject.toml +1 -1
  4. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/__init__.py +1 -1
  5. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/compression_projection.py +40 -19
  6. {fpembed-0.1.6 → fpembed-0.1.7/src/fpembed.egg-info}/PKG-INFO +8 -8
  7. {fpembed-0.1.6 → fpembed-0.1.7}/LICENSE +0 -0
  8. {fpembed-0.1.6 → fpembed-0.1.7}/setup.cfg +0 -0
  9. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/compression.py +0 -0
  10. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/compression_blockwise.py +0 -0
  11. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/generator.py +0 -0
  12. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/hashing.py +0 -0
  13. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/py.typed +0 -0
  14. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed/smiles_utils.py +0 -0
  15. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed.egg-info/SOURCES.txt +0 -0
  16. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed.egg-info/dependency_links.txt +0 -0
  17. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed.egg-info/requires.txt +0 -0
  18. {fpembed-0.1.6 → fpembed-0.1.7}/src/fpembed.egg-info/top_level.txt +0 -0
  19. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_cache.py +0 -0
  20. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_compression.py +0 -0
  21. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_compression_blockwise.py +0 -0
  22. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_compression_projection.py +0 -0
  23. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_fingerprints.py +0 -0
  24. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_generator.py +0 -0
  25. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_hashing.py +0 -0
  26. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_properties.py +0 -0
  27. {fpembed-0.1.6 → fpembed-0.1.7}/tests/test_smiles_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fpembed
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Generalized fingerprint embedding library
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.9
@@ -21,7 +21,7 @@ Dynamic: license-file
21
21
  # FPembed - Generalized Molecular Fingerprint Embeddings
22
22
 
23
23
  [![PyPI version](https://badge.fury.io/py/fpembed.svg)](https://badge.fury.io/py/fpembed)
24
- [![DOI](https://zenodo.org/badge/1223653010.svg)](https://doi.org/10.5281/zenodo.21447996)
24
+ [![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.21447996-blue)](https://doi.org/10.5281/zenodo.21447996)
25
25
 
26
26
 
27
27
  A lightweight Python package for generating compressed molecular fingerprint embeddings, backed by [scikit-fingerprints](https://github.com/scikit-fingerprints/scikit-fingerprints). Supports ten binary fingerprint types through a single unified class.
@@ -142,13 +142,13 @@ Block-wise methods (`geometric`, `linear`, `log`, `uniform`) are fast (O(L)) and
142
142
 
143
143
  All methods produce the same output dimensionality (D = L / compression) but differ in speed and memory:
144
144
 
145
- | Method | Speed | Precomputed Memory | Best For |
146
- |--------|------------------------------------------|--------------------------------------|----------|
147
- | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
148
- | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
149
- | Hadamard (SRHT) | Slowest - pure-Python FWHT, O(L log L) | L-length sign vector (~16 KB) | Small-scale experiments; future optimization |
145
+ | Method | Speed | Precomputed Memory | Best For |
146
+ |--------|------------------------------------------------------------------------------------|--------------------------------------|----------|
147
+ | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
148
+ | Hadamard (SRHT) | Fast - vectorized FWHT (NumPy reshape/broadcast, no Python-level loop), O(L log L) | L-length sign vector (~16 KB) | Large batches at high compression ratios |
149
+ | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
150
150
 
151
- Block-wise methods are ~2–5x faster than random projection and orders of magnitude faster than Hadamard in practice. Random projection's memory cost grows quadratically with fingerprint size.
151
+ Block-wise methods remain the fastest choice for large batches. Hadamard's FWHT is vectorized across the whole batch and works much faster now. Random projection's memory cost grows quadratically with fingerprint size.
152
152
 
153
153
  ## Why Use Embedded Fingerprints?
154
154
 
@@ -1,7 +1,7 @@
1
1
  # FPembed - Generalized Molecular Fingerprint Embeddings
2
2
 
3
3
  [![PyPI version](https://badge.fury.io/py/fpembed.svg)](https://badge.fury.io/py/fpembed)
4
- [![DOI](https://zenodo.org/badge/1223653010.svg)](https://doi.org/10.5281/zenodo.21447996)
4
+ [![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.21447996-blue)](https://doi.org/10.5281/zenodo.21447996)
5
5
 
6
6
 
7
7
  A lightweight Python package for generating compressed molecular fingerprint embeddings, backed by [scikit-fingerprints](https://github.com/scikit-fingerprints/scikit-fingerprints). Supports ten binary fingerprint types through a single unified class.
@@ -122,13 +122,13 @@ Block-wise methods (`geometric`, `linear`, `log`, `uniform`) are fast (O(L)) and
122
122
 
123
123
  All methods produce the same output dimensionality (D = L / compression) but differ in speed and memory:
124
124
 
125
- | Method | Speed | Precomputed Memory | Best For |
126
- |--------|------------------------------------------|--------------------------------------|----------|
127
- | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
128
- | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
129
- | Hadamard (SRHT) | Slowest - pure-Python FWHT, O(L log L) | L-length sign vector (~16 KB) | Small-scale experiments; future optimization |
125
+ | Method | Speed | Precomputed Memory | Best For |
126
+ |--------|------------------------------------------------------------------------------------|--------------------------------------|----------|
127
+ | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
128
+ | Hadamard (SRHT) | Fast - vectorized FWHT (NumPy reshape/broadcast, no Python-level loop), O(L log L) | L-length sign vector (~16 KB) | Large batches at high compression ratios |
129
+ | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
130
130
 
131
- Block-wise methods are ~2–5x faster than random projection and orders of magnitude faster than Hadamard in practice. Random projection's memory cost grows quadratically with fingerprint size.
131
+ Block-wise methods remain the fastest choice for large batches. Hadamard's FWHT is vectorized across the whole batch and works much faster now. Random projection's memory cost grows quadratically with fingerprint size.
132
132
 
133
133
  ## Why Use Embedded Fingerprints?
134
134
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fpembed"
7
- version = "0.1.6"
7
+ version = "0.1.7"
8
8
  description = "Generalized fingerprint embedding library"
9
9
  requires-python = ">=3.9"
10
10
  dependencies = [
@@ -20,7 +20,7 @@ from fpembed.compression import compress_fingerprint
20
20
  from fpembed.smiles_utils import parse_smiles, canonicalize_smiles
21
21
  from fpembed.hashing import fp_params_hash
22
22
 
23
- __version__ = "0.1.6"
23
+ __version__ = "0.1.7"
24
24
 
25
25
  __all__ = [
26
26
  "EmbeddedFingerprintGenerator",
@@ -21,34 +21,59 @@ import numpy as np
21
21
  import numpy.typing as npt
22
22
 
23
23
 
24
- def fwht(x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
25
- """In-place Fast Walsh-Hadamard Transform (butterfly algorithm).
24
+ def _fwht_inplace(x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
25
+ """Vectorized in-place FWHT butterfly, along the last axis.
26
26
 
27
- Operates in O(L log L) using only additions and subtractions.
27
+ Works for a single 1-D vector or a 2-D batch (rows, length) — each
28
+ butterfly level is one NumPy operation over the whole array instead of
29
+ a Python-level loop over individual index pairs. Mutates *x* in-place
30
+ via reshape views (no copy of the full array), matching the original
31
+ per-pair butterfly algorithm exactly.
28
32
 
29
33
  Parameters
30
34
  ----------
31
35
  x : ndarray
32
- 1-D float64 array of length L (must be a power of 2).
36
+ Float64 array whose last axis has length L (must be a power of 2).
33
37
 
34
38
  Returns
35
39
  -------
36
40
  ndarray
37
41
  The same array, modified in-place.
38
42
  """
39
- length = len(x)
43
+ length = x.shape[-1]
40
44
  h = 1
41
45
  while h < length:
42
- for i in range(0, length, h * 2):
43
- for j in range(i, i + h):
44
- a = x[j]
45
- b = x[j + h]
46
- x[j] = a + b
47
- x[j + h] = a - b
46
+ view = x.reshape(*x.shape[:-1], -1, 2, h)
47
+ a = view[..., 0, :].copy()
48
+ b = view[..., 1, :].copy()
49
+ view[..., 0, :] = a + b
50
+ view[..., 1, :] = a - b
48
51
  h *= 2
49
52
  return x
50
53
 
51
54
 
55
+ def fwht(x: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
56
+ """In-place Fast Walsh-Hadamard Transform (butterfly algorithm).
57
+
58
+ Operates in O(L log L) using only additions and subtractions. Vectorized
59
+ via NumPy reshape/broadcast (see `_fwht_inplace`) rather than nested
60
+ Python loops — benchmarked at ~32x faster than the original per-pair
61
+ loop implementation for batched Hadamard compression, with identical
62
+ output (see dev_docs/investigation_compression_acceleration_options.md).
63
+
64
+ Parameters
65
+ ----------
66
+ x : ndarray
67
+ 1-D float64 array of length L (must be a power of 2).
68
+
69
+ Returns
70
+ -------
71
+ ndarray
72
+ The same array, modified in-place.
73
+ """
74
+ return _fwht_inplace(x)
75
+
76
+
52
77
  def build_srht_signs(
53
78
  length: int, seed: int
54
79
  ) -> npt.NDArray[np.float64]:
@@ -102,14 +127,10 @@ def compress_hadamard(
102
127
  output_dim = cols // size
103
128
  norm = 1.0 / np.sqrt(cols)
104
129
 
105
- result = np.empty((rows, output_dim), dtype=np.float64)
106
- for i in range(rows):
107
- row = vector[i].astype(np.float64) * signs
108
- fwht(row)
109
- row *= norm
110
- result[i] = row[:output_dim]
111
-
112
- return result
130
+ signed = vector.astype(np.float64) * signs # broadcasts (rows, cols) * (cols,)
131
+ transformed = _fwht_inplace(signed)
132
+ transformed *= norm
133
+ return transformed[:, :output_dim].copy()
113
134
 
114
135
 
115
136
  def build_rp_matrix(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fpembed
3
- Version: 0.1.6
3
+ Version: 0.1.7
4
4
  Summary: Generalized fingerprint embedding library
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.9
@@ -21,7 +21,7 @@ Dynamic: license-file
21
21
  # FPembed - Generalized Molecular Fingerprint Embeddings
22
22
 
23
23
  [![PyPI version](https://badge.fury.io/py/fpembed.svg)](https://badge.fury.io/py/fpembed)
24
- [![DOI](https://zenodo.org/badge/1223653010.svg)](https://doi.org/10.5281/zenodo.21447996)
24
+ [![DOI](https://img.shields.io/badge/DOI-10.5281/zenodo.21447996-blue)](https://doi.org/10.5281/zenodo.21447996)
25
25
 
26
26
 
27
27
  A lightweight Python package for generating compressed molecular fingerprint embeddings, backed by [scikit-fingerprints](https://github.com/scikit-fingerprints/scikit-fingerprints). Supports ten binary fingerprint types through a single unified class.
@@ -142,13 +142,13 @@ Block-wise methods (`geometric`, `linear`, `log`, `uniform`) are fast (O(L)) and
142
142
 
143
143
  All methods produce the same output dimensionality (D = L / compression) but differ in speed and memory:
144
144
 
145
- | Method | Speed | Precomputed Memory | Best For |
146
- |--------|------------------------------------------|--------------------------------------|----------|
147
- | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
148
- | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
149
- | Hadamard (SRHT) | Slowest - pure-Python FWHT, O(L log L) | L-length sign vector (~16 KB) | Small-scale experiments; future optimization |
145
+ | Method | Speed | Precomputed Memory | Best For |
146
+ |--------|------------------------------------------------------------------------------------|--------------------------------------|----------|
147
+ | Block-wise (all four) | Fastest - single vectorized einsum, O(L) | Negligible (C-length weight vector) | Default choice; large batches |
148
+ | Hadamard (SRHT) | Fast - vectorized FWHT (NumPy reshape/broadcast, no Python-level loop), O(L log L) | L-length sign vector (~16 KB) | Large batches at high compression ratios |
149
+ | Random projection | Fast - BLAS matmul, O(L D) | DxL matrix (~2 MB for L=2048, D=128) | Best theoretical guarantees (JL lemma) |
150
150
 
151
- Block-wise methods are ~2–5x faster than random projection and orders of magnitude faster than Hadamard in practice. Random projection's memory cost grows quadratically with fingerprint size.
151
+ Block-wise methods remain the fastest choice for large batches. Hadamard's FWHT is vectorized across the whole batch and works much faster now. Random projection's memory cost grows quadratically with fingerprint size.
152
152
 
153
153
  ## Why Use Embedded Fingerprints?
154
154
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes