pub struct KnnGraph {
pub adjacency: CscMatrix<f32>,
pub edges: Vec<(usize, usize)>,
pub distances: Vec<f32>,
pub n_nodes: usize,
}Fields§
§adjacency: CscMatrix<f32>Symmetric CSC adjacency matrix (n_nodes x n_nodes)
edges: Vec<(usize, usize)>Sorted edge list (i < j), deduplicated
distances: Vec<f32>Edge distances/weights, parallel to edges
n_nodes: usizeNumber of nodes
Implementations§
Source§impl KnnGraph
impl KnnGraph
Sourcepub fn from_columns(
points: &DMatrix<f32>,
args: KnnGraphArgs,
) -> Result<KnnGraph>
pub fn from_columns( points: &DMatrix<f32>, args: KnnGraphArgs, ) -> Result<KnnGraph>
Build a KNN graph from column vectors.
points- transposed coordinate matrix (d x n), where each column is a pointargs- KNN graph construction parameters
Sourcepub fn from_rows(data: &DMatrix<f32>, args: KnnGraphArgs) -> Result<KnnGraph>
pub fn from_rows(data: &DMatrix<f32>, args: KnnGraphArgs) -> Result<KnnGraph>
Build a KNN graph from row vectors (cells × features).
data- matrix (n x d), where each row is a pointargs- KNN graph construction parameters
Sourcepub fn from_rows_fuzzy(
data: &DMatrix<f32>,
args: KnnGraphArgs,
) -> Result<(KnnGraph, Vec<f32>)>
pub fn from_rows_fuzzy( data: &DMatrix<f32>, args: KnnGraphArgs, ) -> Result<(KnnGraph, Vec<f32>)>
KnnGraph::from_columns_fuzzy over row vectors.
Sourcepub fn from_columns_fuzzy(
points: &DMatrix<f32>,
args: KnnGraphArgs,
) -> Result<(KnnGraph, Vec<f32>)>
pub fn from_columns_fuzzy( points: &DMatrix<f32>, args: KnnGraphArgs, ) -> Result<(KnnGraph, Vec<f32>)>
The kNN graph of the columns of points, and UMAP’s fuzzy membership
of each edge (parallel to edges), as umap-learn and uwot compute it:
- each point’s weights over its OWN
knnneighbours only:exp(-(d - ρ) / σ), ρ its nearest distance, σ set so they sum tolog2(knn + 1)(UMAP counts the point itself among itsn_neighbors, soknnothers isn_neighbors = knn + 1); - zero toward a point it did not list;
- the fuzzy union of the two directions,
a + b - a·b.
KnnGraph::fuzzy_kernel_weights instead calibrates each point over
every edge touching it after the union, so a point many others list
gets a wider kernel and a one-sided edge a weight from both ends.
Sourcepub fn union_with(
&self,
other: &KnnGraph,
policy: DistanceMerge,
) -> Result<(KnnGraph, Vec<EdgeSource>)>
pub fn union_with( &self, other: &KnnGraph, policy: DistanceMerge, ) -> Result<(KnnGraph, Vec<EdgeSource>)>
Merge two graphs over the same nodes, keeping every pair exactly once and reporting which input each came from.
Borrows both inputs: a caller that unions a spatial graph with an expression one generally still needs the spatial graph afterwards, as the topology for anything that reasons about physical adjacency.
Neither input is assumed sorted, nor assumed to store i < j. Edge
order is a constructor invariant here, not a type invariant, and a
hand-built KnnGraph can violate both.
distances after a union are NOT a metric. Under
DistanceMerge::SourceRank they are within-source quantile ranks,
which keeps them comparable across sources without pretending the two
measurements are the same quantity. When an edge is in both inputs the
smaller value wins, matching the reciprocal: false convention in
build_from_dict.
Sourcepub fn neighbors(&self, node: usize) -> &[usize]
pub fn neighbors(&self, node: usize) -> &[usize]
Get neighbors of a node from the CSC adjacency matrix
pub fn num_edges(&self) -> usize
pub fn num_nodes(&self) -> usize
Sourcepub fn exp_kernel_weights(&self) -> Vec<f32>
pub fn exp_kernel_weights(&self) -> Vec<f32>
Convert distances to similarity weights using an exponential kernel:
w = exp(-d / σ) where σ = median distance.
Returns weights parallel to self.edges, all in (0, 1].
Consistent with the softmax(-d) pattern used in counterfactual
inference (data_beans::alg) but with a global bandwidth.
Sourcepub fn fuzzy_kernel_weights(&self) -> Vec<f32>
pub fn fuzzy_kernel_weights(&self) -> Vec<f32>
Adaptive-bandwidth kernel weights with local connectivity.
Per-point sigma calibration (originated in t-SNE, van der Maaten & Hinton 2008) ensures every node has the same effective number of neighbors, preventing isolated singletons in sparse regions. The rho subtraction and fuzzy-union symmetrization follow UMAP (McInnes et al. 2018), matching the scanpy default for Leiden.
Algorithm:
- rho_i = distance to nearest neighbor (local connectivity)
- sigma_i via binary search: sum_j exp(-(d_ij - rho_i)/sigma_i) = log2(k)
- Directed weight: w(i→j) = exp(-(d_ij - rho_i) / sigma_i)
- Symmetrize: w_sym = w(i→j) + w(j→i) - w(i→j) * w(j→i)
Returns weights parallel to self.edges, all in (0, 1].
Source§impl KnnGraph
impl KnnGraph
Sourcepub fn to_leiden_network(&self) -> (Network, f64)
pub fn to_leiden_network(&self) -> (Network, f64)
Convert this KNN graph to a Leiden Network with modularity objective.
Node weights = weighted degree, edge weights = fuzzy kernel weights.
Returns (network, total_edge_weight). Pass total_edge_weight to
modularity_to_cpm_resolution to get a CPM-scale resolution.
Sourcepub fn to_leiden_network_with(&self, weights: &[f32]) -> (Network, f64)
pub fn to_leiden_network_with(&self, weights: &[f32]) -> (Network, f64)
KnnGraph::to_leiden_network with the edge weights given, parallel
to edges (e.g. from KnnGraph::from_rows_fuzzy).
Trait Implementations§
Source§impl WeightedGraph for KnnGraph
impl WeightedGraph for KnnGraph
Auto Trait Implementations§
impl Freeze for KnnGraph
impl RefUnwindSafe for KnnGraph
impl Send for KnnGraph
impl Sync for KnnGraph
impl Unpin for KnnGraph
impl UnsafeUnpin for KnnGraph
impl UnwindSafe for KnnGraph
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.