Create a Single Intersection-weighted k-Nearest Neighbors Graph
Source:R/iknn_graph.R
create.single.iknn.graph.RdCreates and prunes an intersection-weighted k-nearest neighbors (IWD-kNN) graph from input data. The graph is constructed based on feature space distances and intersection sizes between neighbor sets.
Usage
create.single.iknn.graph(
X,
k,
max.path.edge.ratio.deviation.thld = 0.1,
prune.method = c("global.geodesic", "none", "local.geodesic", "global.geodesic.ratio"),
prune.tau = NULL,
prune.local.k = NULL,
path.edge.ratio.percentile = 0.5,
threshold.percentile = 0,
compute.full = FALSE,
with.isize.pruning = FALSE,
with.edge.pruning.stats = FALSE,
pca.dim = 100,
variance.explained = 0.99,
knn.metric = c("euclidean", "linf.simplex"),
linf.tol = sqrt(.Machine$double.eps),
connect.components = FALSE,
connect.method = c("component.mst", "component.mst.ann", "global.mst"),
bridge.k = NULL,
bridge.k.max = NULL,
bridge.growth = 2,
with.lifecycle.branches = FALSE,
verbose = TRUE,
knn.cache.path = NULL,
knn.cache.mode = c("none", "read", "write", "readwrite")
)Arguments
- X
A numeric matrix where rows represent data points and columns represent features. Data frames will be coerced to matrices.
- k
Integer scalar. Number of nearest other vertices. Self is explicitly added to each cover, and distance ties use ascending vertex index. Must be positive and less than the number of data points.
- max.path.edge.ratio.deviation.thld
Numeric in \([0, 0.2)\). Geometric pruning removes an edge \((i,j)\) when there exists an alternative path between \(i\) and \(j\) whose path/edge length ratio minus 1.0 is less than this threshold. This is a deviation threshold \(\delta\) in \([0, 0.2)\). Internally we compare the path-to-edge ratio R to \(1 + \delta\). Used when
prune.methodis"global.geodesic"or"global.geodesic.ratio".- prune.method
Character scalar.
"global.geodesic"preserves the historical whole-graph geometric pruning behavior controlled bymax.path.edge.ratio.deviation.thldandpath.edge.ratio.percentile."global.geodesic.ratio"is a separately named alias for that whole-graph geodesic-ratio behavior."local.geodesic"applies the same experimental local geometric pruning stage used by sKNN/mKNN."none"disables geometric pruning; quantile pruning controlled bythreshold.percentileis still honored.- prune.tau
Numeric scalar greater than 1, or
NULL. Multiplicative threshold for local geometric pruning. IfNULL, defaults tomax(1 + max.path.edge.ratio.deviation.thld, 1.05).- prune.local.k
Integer scalar or
NULL. Number of nearest neighbors used to form local neighborhoods for local geometric pruning. Defaults tok.- path.edge.ratio.percentile
Numeric in \([0,1]\). Only edges with length above this percentile are considered for geometric pruning.
- threshold.percentile
Numeric in \([0, 0.5]\). Percentile threshold for quantile-based edge length pruning. Default is 0 (no quantile pruning). When greater than 0, edges in the top (1 - threshold.percentile) quantile by length are removed if their removal preserves graph connectivity. For example, threshold.percentile = 0.9 removes edges in the top 10\ This pruning is applied after geometric pruning and targets unusually long edges based on absolute edge lengths rather than path-to-edge ratios.
- compute.full
Logical. Retain additional native component diagnostics. Graph stages are always retained; available overlap values are stored as named edge attributes.
- with.isize.pruning
Logical scalar. If TRUE, compute intersection-size pruning outputs and related statistics. Default is FALSE.
- with.edge.pruning.stats
Logical scalar. If TRUE, compute edge-level pruning statistics. Default is FALSE.
- pca.dim
Maximum number of principal components to use if dimensionality reduction is applied (default: 100). Set to NULL to skip dimensionality reduction.
- variance.explained
Percentage of variance to be explained by the principal components (default: 0.99). If this threshold can be met with fewer components than pca.dim, the smaller number will be used. Set to NULL to use exactly pca.dim components.
- knn.metric
Character scalar specifying the geometry used for kNN search.
"euclidean"uses ordinary ambient Euclidean distance."linf.simplex"uses the unfolded intrinsic metric on the \(L^\infty\)-simplex and requires rows ofXto be \(L^\infty\)-normalized.- linf.tol
Positive numeric tolerance used only when
knn.metric = "linf.simplex"to identify active simplex faces and validate thatmax(row) = 1.- connect.components
Logical scalar. If TRUE, add MST bridge edges to the final pruned graph so it is connected whenever possible. Currently supported only with
knn.metric = "euclidean".- connect.method
Character scalar.
"component.mst"adds exact shortest inter-component bridges."component.mst.ann"tries sparse ANN bridge candidates before automatic exact fallback."global.mst"unions the graph with the full Euclidean MST.- bridge.k
Integer scalar or NULL. Initial ANN bridge neighborhood size for
connect.method = "component.mst.ann".- bridge.k.max
Integer scalar or NULL. Maximum ANN bridge neighborhood size before exact fallback.
- bridge.growth
Numeric scalar greater than 1. Multiplicative growth factor for ANN bridge neighborhoods.
- with.lifecycle.branches
Logical scalar. If TRUE, compute the additional repaired lifecycle branches
raw_repaired_*,pruned_repaired_*, andrepaired_pruned_*. This is useful for graph-geodesic reconstruction experiments but can be expensive for the historical global iKNN pruning path, so the default is FALSE.- verbose
Logical. If TRUE, print progress messages. Default is TRUE.
- knn.cache.path
Optional character scalar path to a binary kNN cache file. Used only when
knn.cache.mode != "none".- knn.cache.mode
Character cache mode:
"none": always compute kNN; do not read/write cache."read": read kNN from cache only; if cache is missing/invalid, error."write": always compute kNN and atomically write/overwrite cache."readwrite": read valid cache when available; if cache file is missing, compute and write cache; if cache exists but is invalid, error.
Value
A dgraph object. Use graph.adjacency(), graph.lengths(),
graph.edges() and graph.stages() to inspect its stored graph stages.
Construction and diagnostic information is stored in metadata.
Details
The default accessors inspect the final graph. Use stage = "raw" or
stage = "pruned" to inspect earlier stages. graph.stages() reports
which repaired branches are retained; a missing stage is an error.
Examples
# Create sample data
set.seed(123)
X <- matrix(rnorm(100), ncol = 2)
result <- create.single.iknn.graph(X, k = 3)
#> compute.full=FALSE: optional component diagnostics may be omitted; graph stages are retained.
#> Running single-threaded.
#> [compute_knn] running...
[compute_knn] 0.000s
#> [graph_build (inverted index)] running...
[graph_build (inverted index)] 0.000s
#> [geometric_prune] running...[geometric_prune] evaluating candidates: 0.0% (0/77), removed 0, ETA --:--
[geometric_prune] evaluating candidates: 100.0% (77/77), removed 77, ETA 00:00
[geometric_prune] done: 100.0% (77/77), removed 77, elapsed 0.0s
#>
[geometric_prune] 0.000s
#> [isize_prune] skipped (with.isize.pruning=FALSE)
#> [edge_pruning_stats] skipped (with.edge.pruning.stats=FALSE)
#> Total elapsed time (0.000)
summary(result)
#> Graph Summary:
#> Number of vertices: 50
#> Number of edges: 103
#> Number of edges after pruning: 77
#> Number of edges in final graph: 103
#> Number of removed edges: 77
#> Proportion of edges removed: 0.4277778