Skip to content

Commit 8a08635

Browse files
committed
speed up nystrom
1 parent 8a2fb37 commit 8a08635

2 files changed

Lines changed: 171 additions & 129 deletions

File tree

snapatac2/tools/_embedding.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,12 @@ def spectral(
133133
random_state: int = 0,
134134
sample_size: int | float | None = None,
135135
sample_method: Literal["random", "degree"] = "random",
136-
chunk_size: int = 20000,
136+
chunk_size: int = 5000,
137137
distance_metric: Literal["jaccard", "cosine"] = "cosine",
138138
weighted_by_sd: bool = True,
139139
feature_weights: list[float] | None = None,
140140
inplace: bool = True,
141+
num_threads: int = 32,
141142
) -> tuple[np.ndarray, np.ndarray] | None:
142143
"""
143144
Perform dimension reduction using Laplacian Eigenmaps.
@@ -195,7 +196,8 @@ def spectral(
195196
the full matrix is used. Using this only when the number of cells is too large, e.g. > 10,000,000, or
196197
the `distance_metric` is "jaccard".
197198
chunk_size
198-
Chunk size used in the Nystrom method
199+
Chunk size used in the Nystrom method. The effective chunk size is
200+
`chunk_size` x `num_threads`. This parameter should not be too small, e.g., <1000.
199201
distance_metric
200202
distance metric: "jaccard", "cosine".
201203
When "cosine" is used, the matrix-free spectral embedding algorithm is used.
@@ -208,6 +210,8 @@ def spectral(
208210
frequency (IDF) is used.
209211
inplace
210212
Whether to store the result in the anndata object.
213+
num_threads
214+
Number of threads to use in the Nystrom method.
211215
212216
Returns
213217
-------
@@ -261,7 +265,7 @@ def spectral(
261265
weighted_by_degree = False
262266
else:
263267
weighted_by_degree = True
264-
v, u = internal.spectral_embedding_nystrom(adata, features, n_comps, sample_size, weighted_by_degree, chunk_size)
268+
v, u = internal.spectral_embedding_nystrom(adata, features, n_comps, sample_size, weighted_by_degree, chunk_size, None, num_threads)
265269
evals, evecs = orthogonalize(v, u)
266270
else:
267271
if feature_weights is None:
@@ -395,7 +399,7 @@ def transform(self, orthogonalize = True):
395399
return (self.evals, self.evecs)
396400

397401
def orthogonalize(evals, evecs):
398-
_, sigma, Vt = np.linalg.svd(evecs)
402+
_, sigma, Vt = np.linalg.svd(evecs, full_matrices=False)
399403
V = Vt.T
400404

401405
B = np.multiply(V.T, evals.reshape((1,-1))) @ V

0 commit comments

Comments
 (0)