Skip to content

Commit a22255b

Browse files
committed
ADD: tanimoto similarity
1 parent 4e6493c commit a22255b

1 file changed

Lines changed: 32 additions & 0 deletions

File tree

src/retromol/fingerprint.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,38 @@ def cosine_similarity(fp1: NDArray[np.int8], fp2: NDArray[np.int8]) -> float:
218218
return dot / (na * nb)
219219

220220

221+
def tanimoto_similarity(fp1: NDArray[np.int8], fp2: NDArray[np.int8]) -> float:
222+
"""
223+
Tanimoto similarity for molecular fingerprints (binary or count-based).
224+
225+
:param fp1: first fingerprint (1D array)
226+
:param fp2: second fingerprint (1D array)
227+
:return: Tanimoto similarity in [0, 1]
228+
"""
229+
a = np.asarray(fp1)
230+
b = np.asarray(fp2)
231+
232+
# Ensure 1D
233+
a = a.ravel()
234+
b = b.ravel()
235+
if a.shape != b.shape:
236+
raise ValueError(f"Different lengths: {a.shape} vs {b.shape}")
237+
238+
# Upcast to float to prevent overflow and ensure precision
239+
a = a.astype(np.float64, copy=False)
240+
b = b.astype(np.float64, copy=False)
241+
242+
# Dot product = intersection term
243+
ab = float(np.dot(a, b))
244+
aa = float(np.dot(a, a))
245+
bb = float(np.dot(b, b))
246+
247+
denom = aa + bb - ab
248+
if denom == 0.0:
249+
return 0.0
250+
return ab / denom
251+
252+
221253
def get_kmers(seq: tuple[T, ...], k: int) -> list[tuple[T, ...]]:
222254
"""
223255
Return all contiguous, bidirectional k-mers (subtuples of length k) from a tuple.

0 commit comments

Comments
 (0)