FAQ#
- What does
quadsvstand for? “Quadratic-form spatial variability.” Every test in the library reduces to the quadratic form
\[Q_n = \mathbf{z}^\top \tilde{\mathbf{K}} \mathbf{z},\]where \(\tilde{\mathbf{K}} = \mathbf{H}\mathbf{K}\mathbf{H}\) is the double-centred kernel matrix. See Theoretical Results.
- Why is Moran’s I problematic for SVG detection?
Moran’s I uses an indefinite adjacency matrix as its kernel, so its eigenvalues span both signs. Patterns aligned with positive eigenspaces cancel patterns aligned with negative ones, which produces false negatives. Use the CAR kernel \(\mathbf{K} = (\mathbf{I} - \rho \tilde{\mathbf{W}})^{-1}\) instead. It is strictly positive definite for any \(0 < \rho < 1\). See Theoretical Results (Theorem 2).
from quadsv import MatrixKernel kernel = MatrixKernel.from_coordinates( coords, method="car", k_neighbors=4, rho=0.9 )
- What is the difference between Q-test and R-test?
spatial_q_test()is univariate: \(Q = \mathbf{z}^\top \mathbf{K} \mathbf{z}\). It asks whether one feature is spatially structured under the kernel. Use it to identify spatially variable genes.spatial_r_test()is bivariate: \(R = \mathbf{x}^\top \mathbf{K} \mathbf{y}\). It asks whether two features share a spatial pattern. Use it to find spatially co-expressed gene pairs.- Which backend should I pick?
You can let the
Detector()factory decide from your input type:from quadsv import Detector # AnnData → DetectorIrregular det = Detector(adata, kernel_method="matern", backend="nufft").setup_data(adata) # SpatialData → DetectorGrid det = Detector(sdata, kernel_method="car", rho=0.9).setup_data(sdata, ...)
For explicit control:
Backend
When to use
backend="matrix"(MatrixKernel)Any coordinate cloud or graph. Pick this for
car,moran, orgraph_laplaciankernels, or when you have a precomputed adjacency inadata.obsp. Storage (dense / sparse / sparse-precision) is selected fromn.backend="nufft"(NUFFTKernel)Irregular 2-D coordinates with around \(10^4\) spots or more. Runs at
O(n log n)per feature. Pairs with Gaussian or Matérn.DetectorGrid(FFTKernel)Regular rasterised grids (Visium HD). Reads
spatialdata.SpatialDatadirectly and uses an FFT.- Can I use
quadsvon non-spatial data? Yes, as long as you can encode “closeness” as coordinates or as a graph. Common cases:
A k-NN graph in PCA space (single-cell trajectories).
A pseudo-time ordering or a lineage tree.
A custom adjacency in
adata.obsp.
Pass coordinates to
quadsv.MatrixKernel.from_coordinates(), or a precomputed kernel or precision matrix toquadsv.MatrixKernel.from_matrix(). To use anadata.obsp[key]directly, callsetup_data()withobsp_key=key. Addis_distance=Trueif the matrix stores distances rather than affinities.- Does
quadsvsupport 3-D coordinates? The
MatrixKernelfamily does. Pass 3-D coords toquadsv.MatrixKernel.from_coordinates()the same way you would for 2-D. The FFT and NUFFT backends are 2-D only for now. If you need 3-D Fourier acceleration, please open a feature request on GitHub.
Further help#
Quick Start for the getting-started tour.
Theoretical Results for derivations.
quadsv for the API reference.
GitHub Issues for bug reports and feature requests.