| Title: | Data-Derived Graph Construction Utilities |
|---|---|
| Description: | Constructs data-derived graphs from numerical observations using mutual, shared-neighbor, intersection, geodesic, radius, adaptive-radius, minimum-spanning-tree completion, and optional iterated adaptive neighborhood methods. Provides graph conversion, pruning, diagnostics, spectral embedding, endpoint detection, and path utilities, with reproducible synthetic geometries and point sampling for graph and embedding experiments. The implemented graph constructions include methods described by Jarvis and Patrick (1973) <doi:10.1109/T-C.1973.223640>, Brito et al. (1997) <doi:10.1016/S0167-7152(96)00213-1>, Berry and Sauer (2019) <doi:10.3934/fods.2019001>, and Gower and Ross (1969) <doi:10.2307/2346439>. |
| Authors: | Pawel Gajer [aut, cre], Sunil Arya [ctb] (ANN library), David M. Mount [ctb] (ANN library), University of Maryland [cph] (ANN library), Yixuan Qiu [ctb, cph] (Spectra library), Anna Araslanova [ctb, cph] (Spectra LOBPCG solver), Gael Guennebaud [ctb, cph] (Spectra linear algebra routines), Jitse Niesen [ctb, cph] (Spectra linear algebra routines), Netherlands eScience Center [ctb, cph] (Spectra eigensolver routines), Danil Kirsanov [ctb, cph] (Polyhedral geodesic library) |
| Maintainer: | Pawel Gajer <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0.9000 |
| Built: | 2026-10-01 13:42:26 UTC |
| Source: | https://github.com/pgajer/dgraphs |
Construct and analyze graphs derived from numerical observations.
Finding your way around dgraphs: a task-oriented catalog of public functions and object methods.
Synthetic geometry and point sampling: reproducible curves, surfaces, embeddings and graph examples.
Constructing and Diagnosing Data-Derived Graphs: graph-family comparisons, connectivity repair and diagnostics.
These links open installed HTML guides. From the console, use
vignette("function-guide", package = "dgraphs") or
vignette("synthetic-geometry", package = "dgraphs").
Maintainer: Pawel Gajer [email protected]
Authors:
Pawel Gajer [email protected]
Other contributors:
Sunil Arya (ANN library) [contributor]
David M. Mount (ANN library) [contributor]
University of Maryland (ANN library) [copyright holder]
Yixuan Qiu (Spectra library) [contributor, copyright holder]
Anna Araslanova (Spectra LOBPCG solver) [contributor, copyright holder]
Gael Guennebaud (Spectra linear algebra routines) [contributor, copyright holder]
Jitse Niesen (Spectra linear algebra routines) [contributor, copyright holder]
Netherlands eScience Center (Spectra eigensolver routines) [contributor, copyright holder]
Danil Kirsanov (Polyhedral geodesic library) [contributor, copyright holder]
create.graph(), create.sknn.graph(), create.rknn.graph(),
graph.geodesic.distances(), create.path.graph(), plot.dgraph(),
sample.synthetic.geometry()
graph <- create.graph("chain", n = 5) print(graph) graph.geodesic.distances(graph, vertices = c(1, 5)) # The endpoint distance is four unit-length edges.graph <- create.graph("chain", n = 5) print(graph) graph.geodesic.distances(graph, vertices = c(1, 5)) # The endpoint distance is four unit-length edges.
Convert a dgraph to igraph
as_igraph(graph, stage = "final")as_igraph(graph, stage = "final")
graph |
A |
stage |
Stored graph stage. |
An undirected igraph. Edge lengths are named length; other
attributes retain their names. No implicit weight or unit lengths are
added. For metric paths pass weights = igraph::E(g)$length explicitly;
for hop distance pass weights = NA.
graph <- dgraph(list(2L, 1L, integer()), list(0, 0, numeric())) ig <- as_igraph(graph) igraph::vcount(ig) igraph::E(ig)$lengthgraph <- dgraph(list(2L, 1L, integer()), list(0, 0, numeric())) ig <- as_igraph(graph) igraph::vcount(ig) igraph::E(ig)$length
Compile the pinned IAN and Clarabel sources installed with dgraphs in a new
directory. The supported build target is macOS arm64. Setup requires Python 3,
Apple's C++ compiler/SDK, and matching native Cargo/Rust tools (Rust >= 1.77).
An initial build needs cached crates or network access. No tools are installed
by this function. Compilation is explicit and never starts inside
create.ian.graph() or ordinary package installation.
build.ian.backend( build.dir, python = "python3", cargo = "cargo", rustc = "rustc", cxx = "clang++", offline = FALSE )build.ian.backend( build.dir, python = "python3", cargo = "cargo", rustc = "rustc", cxx = "clang++", offline = FALSE )
build.dir |
New output directory, including logs and source copies. Existing files/directories are refused. A path containing spaces is allowed. |
python |
Python 3 command or executable path. |
cargo |
Cargo command or executable path from a native arm64 toolchain. |
rustc |
Rust compiler command or path from the same toolchain as |
cxx |
C++ compiler command or executable path. |
offline |
Logical scalar. If |
The absolute path to dgraphs_ian.so, invisibly. Save this path and pass
it to create.ian.graph(..., backend = path). Reuse the built module with the
same R installation; rebuild when changing R runtime or backend sources.
Build errors retain available logs and raise an R error. No shared package
library is modified. Build records identify source files and tool commands.
## Not run: backend <- build.ian.backend("ian-build") fit <- create.ian.graph(matrix(c(0, 1, 2), ncol = 1), backend = backend) stopifnot(fit$complete) ## End(Not run)## Not run: backend <- build.ian.backend("ian-build") fit <- create.ian.graph(matrix(c(0, 1, 2), ncol = 1), backend = backend) stopifnot(fit$complete) ## End(Not run)
Builds an iKNN graph sequence and selects k from structural edit-distance
stability, label-mixing stability, or both.
build.iknn.graphs.and.selectk( X, k.values, method = c("both", "edit", "mixing", "none"), pca.dim = 100, variance.explained = 0.99, trim.disconnected = TRUE, edit.min.lcc.frac = 1, edit.eps = 0.05, labels = NULL, perm.blocks = NULL, mixing.metric = c("homophily.effect", "homophily.z", "homophily.adjusted", "assortativity.effect", "assortativity.z", "homophily", "assortativity", "conductance.median", "conductance.wmean"), mixing.min.lcc.frac = 0.98, mixing.eps = 0.05, mixing.require.local.extremum = TRUE, mixing.window = 1L, n.perm = 200L, use.edge.weights = TRUE, weights.are.edge.lengths = FALSE, affinity.method = c("exp", "inv"), affinity.sigma = NULL, affinity.sigma.from = c("k.cc.mixing", "k.max.lcc", "k.trim"), affinity.eps = 1e-08, simplify.multiple = TRUE, seed = 1L, verbose = TRUE, ... )build.iknn.graphs.and.selectk( X, k.values, method = c("both", "edit", "mixing", "none"), pca.dim = 100, variance.explained = 0.99, trim.disconnected = TRUE, edit.min.lcc.frac = 1, edit.eps = 0.05, labels = NULL, perm.blocks = NULL, mixing.metric = c("homophily.effect", "homophily.z", "homophily.adjusted", "assortativity.effect", "assortativity.z", "homophily", "assortativity", "conductance.median", "conductance.wmean"), mixing.min.lcc.frac = 0.98, mixing.eps = 0.05, mixing.require.local.extremum = TRUE, mixing.window = 1L, n.perm = 200L, use.edge.weights = TRUE, weights.are.edge.lengths = FALSE, affinity.method = c("exp", "inv"), affinity.sigma = NULL, affinity.sigma.from = c("k.cc.mixing", "k.max.lcc", "k.trim"), affinity.eps = 1e-08, simplify.multiple = TRUE, seed = 1L, verbose = TRUE, ... )
X |
Numeric observation-by-feature matrix. |
k.values |
Strictly increasing integer vector of neighborhood sizes, each between 1 and n - 1. |
method |
Selection criterion. |
pca.dim, variance.explained
|
PCA controls forwarded to
|
trim.disconnected |
Logical; trim to a largest connected component when the requested connectivity tail is absent. |
edit.min.lcc.frac, edit.eps
|
Connectivity and tolerance controls for edit-distance selection. |
labels, perm.blocks
|
Optional labels and permutation blocks for mixing selection. |
mixing.metric, mixing.min.lcc.frac, mixing.eps
|
Mixing criterion, connectivity threshold, and tolerance. |
mixing.require.local.extremum, mixing.window
|
Local-extremum controls for the mixing curve. |
n.perm |
Number of label permutations. |
use.edge.weights, weights.are.edge.lengths
|
Edge-weight interpretation. |
affinity.method, affinity.sigma, affinity.sigma.from, affinity.eps
|
Controls for converting edge lengths to affinities. |
simplify.multiple |
Logical; simplify loops and multiple edges. |
seed |
Random seed. |
verbose |
Logical; report progress. |
... |
Additional arguments forwarded to |
An object of class "build_iknn_graphs_and_selectk" containing the
graph sequence, connectivity diagnostics, selection curves, selected
neighborhood sizes, trimming metadata, and call parameters.
set.seed(1) x <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(x, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) selected$k.opt.editset.seed(1) x <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(x, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) selected$k.opt.edit
Compare Two Adjacency Lists
compare.adj.lists(adj.list1, adj.list2, verbose = FALSE)compare.adj.lists(adj.list1, adj.list2, verbose = FALSE)
adj.list1 |
First adjacency list. |
adj.list2 |
Second adjacency list. |
verbose |
Logical; print the indices of vertices with different
neighbor sets. Defaults to |
TRUE when each vertex has the same neighbor set in both lists,
ignoring order; otherwise FALSE.
graph <- list(c(2L, 3L), 1L, 1L) compare.adj.lists(graph, list(c(3L, 2L), 1L, 1L))graph <- list(c(2L, 3L), 1L, 1L) compare.adj.lists(graph, list(c(3L, 2L), 1L, 1L))
Compare Paths Across Hop Limits
compare.paths(path.result, from, to)compare.paths(path.result, from, to)
path.result |
A |
from |
Source vertex index. |
to |
Target vertex index. |
Data frame describing path availability and length by hop limit.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) series <- create.path.graph(dgraph(graph, lengths), h.values = 1:2) compare.paths(series, from = 1, to = 3)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) series <- create.path.graph(dgraph(graph, lengths), h.values = 1:2) compare.paths(series, from = 1, to = 3)
Analyzes how the number of geodesics scales with radius for each grid vertex. This function helps determine if collapsing/clustering geodesics is necessary and provides insights into the graph structure around grid vertices.
compute.geodesic.stats( adj.list, length.list, min.radius = 0.2, max.radius = 0.5, n.steps = 5, n.packing.vertices = length(adj.list), max.packing.iterations = 20, packing.precision = 1e-04, verbose = FALSE )compute.geodesic.stats( adj.list, length.list, min.radius = 0.2, max.radius = 0.5, n.steps = 5, n.packing.vertices = length(adj.list), max.packing.iterations = 20, packing.precision = 1e-04, verbose = FALSE )
adj.list |
List of integer vectors. Each vector contains indices of vertices adjacent to the corresponding vertex. Indices should be 1-based. |
length.list |
List of numeric vectors. Each vector contains weights of edges corresponding to adjacencies in adj.list. |
min.radius |
Numeric. Minimum radius as a fraction of graph diameter. |
max.radius |
Numeric. Maximum radius as a fraction of graph diameter. |
n.steps |
Integer. Number of radius steps to test. |
n.packing.vertices |
Integer. Number of vertices in the grid/packing. |
max.packing.iterations |
Integer. Maximum iterations for packing algorithm. |
packing.precision |
Numeric. Precision parameter for packing algorithm. |
verbose |
Logical. Whether to print progress information. |
A list of class "geodesic_stats" containing:
Numeric vector. Actual radii used in the analysis.
Matrix. Number of geodesic rays for each vertex at each radius.
Matrix. Number of composite geodesics for each vertex at each radius.
List of matrices. Overlap statistics for each vertex at each radius.
Integer vector. The vertices selected as grid vertices.
Data frame. Summary statistics for each radius.
graph <- create.graph("circle", n = 8, sampling = "uniform") stats <- compute.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), min.radius = 0.3, max.radius = 0.5, n.steps = 2, n.packing.vertices = 4) stats$summarygraph <- create.graph("circle", n = 8, sampling = "uniform") stats <- compute.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), min.radius = 0.3, max.radius = 0.5, n.steps = 2, n.packing.vertices = 4) stats$summary
Compute a Weighted Graph Diameter
compute.graph.diameter(graph, stage = "final")compute.graph.diameter(graph, stage = "final")
graph |
A |
stage |
Stored graph stage. |
A list containing the diameter and the farthest path details.
graph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) compute.graph.diameter(dgraph(graph, weights))$diametergraph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) compute.graph.diameter(dgraph(graph, weights))$diameter
Compute a Weighted Shortest-Path Distance
compute.graph.distance(graph, i, j, stage = "final")compute.graph.distance(graph, i, j, stage = "final")
graph |
A |
i |
Source vertex. |
j |
Target vertex. |
stage |
Stored graph stage. |
Numeric shortest-path distance.
graph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) compute.graph.distance(i = 1, j = 3, graph = dgraph(graph, weights))graph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) compute.graph.distance(i = 1, j = 3, graph = dgraph(graph, weights))
Computes endpointness diagnostics for graph vertices by selecting graph-geodesic neighborhoods and evaluating how concentrated the corresponding 3D embedding directions are. This targets terminal arm tips in an embedding rather than graph-theoretic degree-1 vertices.
For each vertex , let be unit vectors in the
embedding from to graph-geodesic neighbors of . The function
computes:
Neighborhoods are selected in graph-geodesic space while directions are taken from the supplied 3D embedding.
compute.graph.endpoint.scores( adj.list, length.list, layout.3d, neighborhood = c("geodesic_k", "geodesic_radius"), k = c(10L, 20L, 30L), radius = NULL, q = 0.1, neighbor.weighting = c("uniform", "inverse_distance", "gaussian"), gaussian.sigma = NULL, min.neighborhood.size = 3L, scale.aggregate = c("mean", "median", "min", "max"), verbose = FALSE )compute.graph.endpoint.scores( adj.list, length.list, layout.3d, neighborhood = c("geodesic_k", "geodesic_radius"), k = c(10L, 20L, 30L), radius = NULL, q = 0.1, neighbor.weighting = c("uniform", "inverse_distance", "gaussian"), gaussian.sigma = NULL, min.neighborhood.size = 3L, scale.aggregate = c("mean", "median", "min", "max"), verbose = FALSE )
adj.list |
Graph adjacency list (1-based vertex indices). |
length.list |
Edge-length list aligned with |
layout.3d |
Numeric matrix or data frame with 3 columns giving the 3D embedding coordinates for graph vertices. |
neighborhood |
Character string. Either |
k |
Integer vector of geodesic neighborhood sizes used when
|
radius |
Positive numeric vector of geodesic radii used when
|
q |
Quantile used for |
neighbor.weighting |
Character string controlling neighbor weights for
|
gaussian.sigma |
Optional positive numeric scale used when
|
min.neighborhood.size |
Minimum number of usable neighbors required after
removing zero-length embedding vectors. Must be at least |
scale.aggregate |
How to aggregate scores across multiple neighborhood
scales. One of |
verbose |
Logical; if |
A list with aggregated per-vertex scores, per-scale score matrices, and neighborhood diagnostics.
chain <- create.graph("chain", n = 8) layout <- cbind(seq_len(8), 0, 0) scores <- compute.graph.endpoint.scores(graph.adjacency(chain), graph.lengths(chain), layout, k = c(2, 3), min.neighborhood.size = 2) head(scores$summary)chain <- create.graph("chain", n = 8) layout <- cbind(seq_len(8), 0, 0) scores <- compute.graph.endpoint.scores(graph.adjacency(chain), graph.lengths(chain), layout, k = c(2, 3), min.neighborhood.size = 2) head(scores$summary)
Converts a graph-like object into a named probability mass function (PMF)
describing one selected graph summary. This provides a standardized bridge
between graph objects and divergence functions such as
jensen.shannon.divergence().
Supported v1 summaries are:
"degree_distribution"
"edge_weight_distribution"
"component_size_distribution"
"neighborhood_label_distribution"
"component_size_distribution" is included primarily as a diagnostic
for disconnectedness / fragmentation, not as a general-purpose default
stability summary.
compute.graph.summary.pmf( graph, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), labels = NULL, edge.attribute = "length", stage = "final", bins = NULL, n.bins = 20L, bin.method = c("auto", "fixed_width", "fixed_quantile", "explicit"), normalize = TRUE, support = NULL, zero.pad = TRUE, return.details = TRUE )compute.graph.summary.pmf( graph, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), labels = NULL, edge.attribute = "length", stage = "final", bins = NULL, n.bins = 20L, bin.method = c("auto", "fixed_width", "fixed_quantile", "explicit"), normalize = TRUE, support = NULL, zero.pad = TRUE, return.details = TRUE )
graph |
A |
summary |
Summary type to compute. |
labels |
Optional label vector used for
|
edge.attribute |
Edge quantity for the edge-value distribution; default |
stage |
Stored graph stage to summarize. |
bins |
Optional numeric vector of histogram breaks used for
|
n.bins |
Integer number of bins used when |
bin.method |
Character string controlling automatic bin construction for
|
normalize |
Logical; if |
support |
Optional support to align the resulting PMF to. |
zero.pad |
Logical; if |
return.details |
Logical; if |
If return.details = TRUE, a list with fields:
summary: summary type used.
pmf: named probability mass function.
support: support of the PMF.
counts: named raw-count vector before normalization.
metadata: list of summary-specific metadata.
Otherwise, returns the named PMF vector.
graph <- dgraph(list(c(2L, 3L), 1L, 1L)) compute.graph.summary.pmf(graph, summary = "degree_distribution")graph <- dgraph(list(c(2L, 3L), 1L, 1L)) compute.graph.summary.pmf(graph, summary = "degree_distribution")
Computes a divergence-based stability curve across consecutive graphs in a
sequence. This function provides a generalized sequence-level analogue of the
degree-profile Jensen-Shannon calculation currently used in
compute.stability.metrics().
compute.graph.summary.stability( graphs, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list(), k.values = NULL, graph.type = c("geom", "isize"), return.details = TRUE )compute.graph.summary.stability( graphs, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list(), k.values = NULL, graph.type = c("geom", "isize"), return.details = TRUE )
graphs |
Either a list of graph-like objects or an object of class
|
summary |
Summary type to compare across consecutive graph pairs. |
divergence |
Divergence type. Currently only |
labels |
Optional shared vertex-label vector used for
|
summary.args |
Optional named list forwarded to
|
k.values |
Optional integer vector of k values. If |
graph.type |
If |
return.details |
Logical; if |
If return.details = TRUE, a list with fields:
summary: summary type used.
divergence: divergence type used.
k.values: full k sequence.
k.transition.values: k values corresponding to consecutive-graph
transitions.
values: vector of divergence values of length length(k.values) - 1.
details: optional pairwise details for each transition.
Otherwise, returns only the divergence vector.
graphs <- list( dgraph(list(2L, c(1L, 3L), 2L)), dgraph(list(c(2L, 3L), c(1L, 3L), c(1L, 2L))), create.graph("complete", 3) ) compute.graph.summary.stability( graphs, summary = "degree_distribution" )$valuesgraphs <- list( dgraph(list(2L, c(1L, 3L), 2L)), dgraph(list(c(2L, 3L), c(1L, 3L), c(1L, 2L))), create.graph("complete", 3) ) compute.graph.summary.stability( graphs, summary = "degree_distribution" )$values
Computes stability diagnostics across the pruned IkNN graphs produced by
create.iknn.graphs(). Metrics include edit distances between consecutive
graphs, graph-summary Jensen-Shannon divergence, edge-count diagnostics,
local minima, and smoothed trend fits for plotting.
compute.stability.metrics( graphs, graph.type = c("geom", "isize"), summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list() )compute.stability.metrics( graphs, graph.type = c("geom", "isize"), summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list() )
graphs |
An object of class |
graph.type |
Character string, either |
summary |
Graph-summary family used for the divergence curve. |
divergence |
Divergence used for consecutive-graph comparison.
Currently only |
labels |
Optional vertex-label vector used when
|
summary.args |
Optional named list forwarded to
|
An object of class "iknn_stability_metrics".
set.seed(1) x <- matrix(rnorm(60), ncol = 2) graphs <- create.iknn.graphs(x, k.values = seq.int(2, 4), compute.full = TRUE, verbose = FALSE) stability <- compute.stability.metrics(graphs) stability$edit.distancesset.seed(1) x <- matrix(rnorm(60), ncol = 2) graphs <- create.iknn.graphs(x, k.values = seq.int(2, 4), compute.full = TRUE, verbose = FALSE) stability <- compute.stability.metrics(graphs) stability$edit.distances
Analyzes how the number of geodesics scales with radius for a specific grid vertex.
compute.vertex.geodesic.stats( adj.list, length.list, grid.vertex, min.radius = 0.2, max.radius = 0.5, n.steps = 5, n.packing.vertices = length(adj.list), packing.precision = 1e-04 )compute.vertex.geodesic.stats( adj.list, length.list, grid.vertex, min.radius = 0.2, max.radius = 0.5, n.steps = 5, n.packing.vertices = length(adj.list), packing.precision = 1e-04 )
adj.list |
List of integer vectors. Each vector contains indices of vertices adjacent to the corresponding vertex. Indices should be 1-based. |
length.list |
List of numeric vectors. Each vector contains weights of edges corresponding to adjacencies in adj.list. |
grid.vertex |
Integer. The grid vertex to analyze. |
min.radius |
Numeric. Minimum radius as a fraction of graph diameter. |
max.radius |
Numeric. Maximum radius as a fraction of graph diameter. |
n.steps |
Integer. Number of radius steps to test. |
n.packing.vertices |
Integer. Number of vertices in the grid/packing. |
packing.precision |
Numeric. Precision threshold for packing convergence. |
A data frame of class "vertex_geodesic_stats" with columns:
Actual radius used.
Number of geodesic rays within radius.
Number of composite geodesics.
Minimum overlap ratio.
5th percentile overlap ratio.
25th percentile overlap ratio.
Median overlap ratio.
75th percentile overlap ratio.
95th percentile overlap ratio.
Maximum overlap ratio.
graph <- create.graph("circle", n = 8, sampling = "uniform") compute.vertex.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), grid.vertex = 1, min.radius = 0.3, max.radius = 0.5, n.steps = 2)graph <- create.graph("circle", n = 8, sampling = "uniform") compute.vertex.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), grid.vertex = 1, min.radius = 0.3, max.radius = 0.5, n.steps = 2)
Convert an Adjacency List to an Adjacency Matrix
convert.adjacency.list.to.adjacency.matrix( adj.list, weight.list = NULL, mode = "undirected", remove.self.loops = TRUE )convert.adjacency.list.to.adjacency.matrix( adj.list, weight.list = NULL, mode = "undirected", remove.self.loops = TRUE )
adj.list |
Adjacency list. |
weight.list |
Optional edge-weight list aligned with |
mode |
Either |
remove.self.loops |
Logical; if |
Numeric adjacency matrix.
graph <- list(c(2L, 3L), 1L, 1L) weights <- list(c(1, 2), 1, 2) convert.adjacency.list.to.adjacency.matrix(graph, weights)graph <- list(c(2L, 3L), 1L, 1L) weights <- list(c(1, 2), 1, 2) convert.adjacency.list.to.adjacency.matrix(graph, weights)
Convert an Adjacency List to an Edge Matrix
convert.adjacency.to.edge.matrix(adj.list, weight.list = NULL)convert.adjacency.to.edge.matrix(adj.list, weight.list = NULL)
adj.list |
A 1-based adjacency list. |
weight.list |
Optional edge-weight list aligned with |
A list with edge.matrix and weights.
graph <- list(c(2L, 3L), 1L, 1L) convert.adjacency.to.edge.matrix(graph)graph <- list(c(2L, 3L), 1L, 1L) convert.adjacency.to.edge.matrix(graph)
Convert a Directed Adjacency List to an Undirected Adjacency List
convert.to.undirected(adj.list)convert.to.undirected(adj.list)
adj.list |
Directed adjacency list. |
An adjacency list with reciprocal edges added and duplicate neighbors removed.
directed <- list(2L, integer(0), 1L) convert.to.undirected(directed)directed <- list(2L, integer(0), 1L) convert.to.undirected(directed)
Convert a Weighted Adjacency Matrix to Lists
convert.weighted.adjacency.matrix.to.adjacency.list(A)convert.weighted.adjacency.matrix.to.adjacency.list(A)
A |
Numeric square adjacency matrix. |
A list with adj.list and weight.list.
A <- matrix(c(0, 1, 0, 1, 0, 2, 0, 2, 0), nrow = 3) convert.weighted.adjacency.matrix.to.adjacency.list(A)A <- matrix(c(0, 1, 0, 1, 0, 2, 0, 2, 0), nrow = 3) convert.weighted.adjacency.matrix.to.adjacency.list(A)
Count Edges in an Undirected Adjacency List
count.edges(adj.list)count.edges(adj.list)
adj.list |
Adjacency list for an undirected graph. |
Number of undirected edges.
count.edges(list(c(2L, 3L), 1L, 1L))count.edges(list(c(2L, 3L), 1L, 1L))
Creates an undirected continuous-kNN graph using local scale distances.
Let be the distance from observation to its
k.scale-th non-self nearest neighbor. Vertices are adjacent when
This is a convenience wrapper around create.rknn.graph() with
type = "adaptive.radius" and radius.rule = "geomean". It is useful as
a named data-derived graph construction in geodesic reconstruction
benchmarks.
create.cknn.graph( X, k.scale, delta = 1, radius.search = c("ann", "all.pairs"), return.timing = FALSE, graph.detail = c("full", "minimal"), prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )create.cknn.graph( X, k.scale, delta = 1, radius.search = c("ann", "all.pairs"), return.timing = FALSE, graph.detail = c("full", "minimal"), prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )
X |
Numeric matrix or data frame with observations in rows. |
k.scale |
Positive integer smaller than |
delta |
Positive numeric scalar multiplying the geometric-mean adaptive radius. |
radius.search |
Character scalar. |
return.timing |
Logical scalar. If |
graph.detail |
Character scalar. |
prune.method |
Character scalar. |
max.path.edge.ratio.deviation.thld |
Numeric scalar in |
path.edge.ratio.percentile |
Numeric scalar in |
prune.tau |
Numeric scalar greater than 1. For local geometric pruning, an edge may be removed when a retained local alternative path is at most this multiplicative factor times the direct edge length. |
prune.local.k |
Integer scalar or |
with.pruned.edge.stats |
Logical scalar. If |
connect.components |
Logical scalar. If |
connect.method |
Character scalar. |
bridge.k |
Integer scalar or |
bridge.k.max |
Integer scalar or |
bridge.growth |
Numeric scalar greater than 1. Multiplicative growth factor for ANN bridge neighborhoods. |
A list inheriting from "cknn_graph" and "adaptive_radius_graph".
It contains the same lifecycle fields as create.rknn.graph() with
type = "adaptive.radius", radius_rule = "geomean",
radius_factor = delta, and graph_rule = "continuous.knn".
X <- matrix(c(0, 1, 3), ncol = 1) as.matrix(graph.edges(create.cknn.graph(X, k.scale = 1, delta = 1))[, c("from", "to")])X <- matrix(c(0, 1, 3), ncol = 1) as.matrix(graph.edges(create.cknn.graph(X, k.scale = 1, delta = 1))[, c("from", "to")])
Constructs a completion of the Minimal Spanning Tree (MST) graph from a numeric data matrix. The graph is constructed in two steps: first, a MST is built connecting all data points using minimal total edge length; then, additional edges are added between any pair of points whose Euclidean distance is less than or equal to a quantile threshold based on the MST edge length distribution.
create.cmst.graph( X, q.thld = 0.9, pca.dim = 100, variance.explained = 0.99, verbose = TRUE )create.cmst.graph( X, q.thld = 0.9, pca.dim = 100, variance.explained = 0.99, verbose = TRUE )
X |
A numeric matrix or data frame of shape |
q.thld |
Numeric scalar between 0 and 1 (exclusive). The quantile threshold for MST completion. Edges are added between points whose distance is less than or equal to the q.thld-quantile of MST edge weights. Default is 0.9. |
pca.dim |
Positive integer or NULL. If provided and |
variance.explained |
Numeric between 0 and 1 (exclusive) or NULL. If
provided, selects the minimal number of PCA components such that this
proportion of total variance is retained (up to |
verbose |
Logical. If |
The MST completion process enhances connectivity in the original MST by adding edges between vertices that are "close" according to the distance distribution in the MST. This can be useful for creating more robust graph representations of data that maintain local structure while avoiding long-range connections.
When PCA is applied (either through pca.dim or variance.explained),
the data is first centered and projected onto the leading principal components
before graph construction. This can significantly reduce computation time
for high-dimensional data while preserving the most important variation.
A dgraph with raw (MST) and final (completed) stages.
Use graph accessors to inspect topology and lengths; construction details
are in metadata.
Gower, J. C., & Ross, G. J. S. (1969). Minimum spanning trees and single linkage cluster analysis. Applied Statistics, 18(1), 54-64.
stats::prcomp() for principal component analysis.
set.seed(123) X <- matrix(rnorm(60), nrow = 20, ncol = 3) graph <- create.cmst.graph(X, verbose = FALSE) graph.order(graph) nrow(graph.edges(graph))set.seed(123) X <- matrix(rnorm(60), nrow = 20, ncol = 3) graph <- create.cmst.graph(X, verbose = FALSE) graph.order(graph) nrow(graph.edges(graph))
Each cover contains its source vertex plus its k nearest other vertices.
Equal distances are resolved by ascending vertex index. Intersecting covers
create edges whose lengths are shortest-path distances in the input graph.
create.geodesic.iknn.graph(graph, k, small.component = c("error", "truncate"))create.geodesic.iknn.graph(graph, k, small.component = c("error", "truncate"))
graph |
A |
k |
Number of nearest other vertices; integer |
small.component |
Default |
A dgraph with a final stage, lengths and an overlap edge attribute.
metadata$neighborhood records requested and effective sizes and the tie rule.
graph <- create.graph("chain", 3) create.geodesic.iknn.graph(graph, k = 1)graph <- create.graph("chain", 3) create.geodesic.iknn.graph(graph, k = 1)
Construct a standard topology or a simple geometric graph. All types return
a dgraph() and use compact, 1-based adjacency indices. type is required;
type names and names in ... must match exactly.
create.graph(type, n = NULL, ..., labels = NULL)create.graph(type, n = NULL, ..., labels = NULL)
type |
Graph type: |
n |
Number of vertices. Required except when inferred from chain |
... |
Named type-specific arguments, described below. Unknown, duplicated, unnamed and irrelevant arguments error. |
labels |
Optional unique, nonmissing character or numeric vertex labels,
one per vertex. Labels name adjacency lists and are stored in
|
A dgraph with one final stage and construction information in
metadata, including type. Inspect it with graph.adjacency(),
graph.lengths(), graph.edges() and graph.order().
empty, complete, cycle
Only n and labels. These return
topology without stored lengths. A cycle closes a chain with one edge.
chainspan = 1 connects up to span positions on each side,
giving at most 2 * span neighbors. It must be an integer from 1 to
n - 1; it does not use the nearest-neighbor meaning of k.
Optional finite numeric x orders vertices by coordinate (ties by input
position) and supplies absolute coordinate differences as lengths.
Without x, lengths are one. Optional vector y requires x and is
reordered with it. Metadata contains order (sorted-to-input indices),
x.sorted and y.sorted.
complete_bipartiteRequired sizes, two positive integers.
All pairs across the two parts are connected; there are no within-part
edges or stored lengths. Vertices in the first part come first.
starRequired arms, at least two positive integer edge counts.
Chains of those lengths share vertex 1 as their center. Thus
n = 1 + sum(arms); all-one arms give an ordinary star. Vertices are
numbered along successive arms. No lengths are stored.
circlesampling = "uniform" or "random" (default),
edge.length = "arc" (default) or "chord", and optional seed.
Vertices are ordered by angle on the unit circle and consecutive
vertices, including last-to-first, are connected. Arc lengths measure
the shorter unit-circle arc between endpoints, even when the gap in
the sampling order exceeds pi. Chords are Euclidean distances.
Metadata contains angles (radians) and coordinates (x/y columns).
randomRequired finite mean.degree, connected = TRUE, and
optional seed. The edge count is floor(n * mean.degree / 2);
0 <= mean.degree <= n - 1. If connected, this count must be at least
n - 1. A randomly ordered growing tree is built first, then a uniform
subset of remaining pairs is added. This is not uniform sampling over
connected graphs or spanning trees. If disconnected graphs are allowed,
a uniform subset of all pairs is sampled. Each undirected edge receives
one independent length uniform between 0.5 and 1.5. Candidate-pair storage is
quadratic in n; this constructor is intended for small examples.
Metadata records requested and realized mean degrees and connectivity.
For random and circle, seed = NULL uses and advances the caller's
current random stream. An explicit nonnegative integer seed makes the call
reproducible under the current RNG kind and restores the caller's RNG state
afterwards, including an initially absent state. Uniform circle sampling
consumes no random numbers. The richer geometry sampling API has its own
seed/state continuation contract; see sample.synthetic.geometry().
graph.order(create.graph("empty", n = 4)) graph.edges(create.graph("complete", n = 3)) chain <- create.graph("chain", x = c(3, 1, 2), span = 1, labels = c("third", "first", "second")) graph.adjacency(chain) graph.lengths(chain) graph.edges(create.graph("cycle", n = 4)) graph.order(create.graph("complete_bipartite", sizes = c(2, 3))) graph.order(create.graph("star", arms = c(2, 3, 1))) graph.edges(create.graph("random", n = 6, mean.degree = 2, seed = 10)) circle <- create.graph("circle", n = 8, sampling = "uniform", edge.length = "chord") circle$metadata$coordinatesgraph.order(create.graph("empty", n = 4)) graph.edges(create.graph("complete", n = 3)) chain <- create.graph("chain", x = c(3, 1, 2), span = 1, labels = c("third", "first", "second")) graph.adjacency(chain) graph.lengths(chain) graph.edges(create.graph("cycle", n = 4)) graph.order(create.graph("complete_bipartite", sizes = c(2, 3))) graph.order(create.graph("star", arms = c(2, 3, 1))) graph.edges(create.graph("random", n = 6, mean.degree = 2, seed = 10)) circle <- create.graph("circle", n = 8, sampling = "uniform", edge.length = "chord") circle$metadata$coordinates
Create a Refined Graph with Approximately Uniform Edge Spacing
create.grid.graph( adj.list, length.list, grid.size, start.vertex = 1L, snap.tolerance = 0.1 )create.grid.graph( adj.list, length.list, grid.size, start.vertex = 1L, snap.tolerance = 0.1 )
adj.list |
Input graph adjacency list. |
length.list |
Edge-length list matching |
grid.size |
Target grid size parameter. |
start.vertex |
Starting vertex used for breadth-first grid placement. |
snap.tolerance |
Grid snapping tolerance. |
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.
chain <- create.graph("chain", n = 3) grid <- create.grid.graph(graph.adjacency(chain), graph.lengths(chain), grid.size = 5) grid$metadata$grid_verticeschain <- create.graph("chain", n = 3) grid <- create.grid.graph(graph.adjacency(chain), graph.lengths(chain), grid.size = 5) grid$metadata$grid_vertices
Construct the initial Gabriel graph, adapt local scales and prune edges, returning graphs, affinities and diagnostics. By default, proposed bridge edges are protected so that pruning retains connectivity, and the audited retry-power numerical policy permits one checked retry after an eligible solver rejection. These are explicit variants of reference IAN.
create.ian.graph( X, distances = NULL, specimen.ids = NULL, participant.ids = NULL, graph = NULL, diagnostics = c("summary", "full"), backend = NULL, max.solves = 10000L, numerical.policy = "IAN evaluated-LP retry-power 0.1", preserve.connectivity = TRUE )create.ian.graph( X, distances = NULL, specimen.ids = NULL, participant.ids = NULL, graph = NULL, diagnostics = c("summary", "full"), backend = NULL, max.solves = 10000L, numerical.policy = "IAN evaluated-LP retry-power 0.1", preserve.connectivity = TRUE )
X |
Finite numeric specimen-by-feature matrix, at least two rows and one
column. There is no fixed experimental row cap. Input size must fit R/native
index representations and available memory. Dense distances and affinities
require quadratic storage: each n-by-n double matrix uses |
distances |
Optional unsquared distance matrix or |
specimen.ids |
Unique nonempty IDs; defaults to row names or row numbers. |
participant.ids |
Optional specimen-level nonempty IDs, possibly repeated. |
graph |
Reserved supplied-graph argument; currently must be |
diagnostics |
|
backend |
Optional path to the separately built |
max.solves |
Positive integer safety limit; reaching it returns refusal. |
numerical.policy |
Exactly |
preserve.connectivity |
Logical scalar, default |
Build the optional module once with build.ian.backend() and pass its returned
path as backend. The supported build target is macOS arm64. The function
itself does not compile code, download dependencies or launch an external
solver. See system.file("ian", "README.md", package = "dgraphs") for the
numerical contract, setup requirements and bounded qualification.
Input rows are specimens; graph vertices are unique feature profiles in
first-occurrence order. Always check complete before using final_graph.
Invalid R arguments or an unavailable backend raise an R error. Numerical
refusal and interruption during engine execution return an incomplete result
with the available diagnostics. Memory exhaustion or process termination is
not a recoverable-result guarantee.
The default numerical policy is IAN evaluated-LP retry-power 0.1.
A rejected original return remains rejected. Its single eligible retry must
itself pass strict solver success and the unchanged original-unit checks.
numerical.policy="IAN evaluated-LP 1.0" together with
preserve.connectivity=FALSE selects the previous strict/reference behavior.
This public default adoption changes neither policy's implementation.
The returned top-level fields are complete, error, initial_graph,
final_graph, last_valid_graph, mapping, scales, affinity,
diagnostics and backend. Graphs are dgraph() objects with metric edge
lengths in input distance units; affinity values are separate similarities.
Mapping contains one-based representatives and member_to_profile, plus
specimen, profile and participant IDs. Repeated participant IDs do not merge
specimens. Error information contains kind, code and message.
diagnostics$solver_history retains both accepted and rejected attempts.
Backend information identifies the selected policies, source and settings.
Checkpoint/resume is not exposed through this R interface.
A list with complete, structured error, initial Gabriel graph,
final_graph only on full completion, last_valid_graph (possibly partial),
profile mapping, local scales and an affinity matrix distinct from metric
edge lengths. Graph indices and mappings are one-based. Full traces retain
original zero-based core indices and declare this in diagnostics. Summary diagnostics
include per-solve status, acceptance, settings, residuals and iteration counts.
Refusal and interruption return incomplete structured results; invalid R
arguments error before native execution. Interrupts are checked at engine
events; they do not interrupt an active solver call. In connectivity mode,
diagnostics$connectivity contains protected.edges (one-based profile
rows and IDs, first/last encounter iteration, count and first statistic),
per-iteration history, and stop.reason. Iterations in this summary are
one-based. Protected edges are encountered proposals, not necessarily edges
that would pass the pruning criteria. Full traces also include every edge
proposal and whether eligibility was tested. A complete pass with no
deletion stops, including when statistical candidates remain protected.
Partial results retain available protection diagnostics; final_graph
remains NULL if later optimization or affinity construction fails.
# Set this variable to the path returned by build.ian.backend(). backend <- Sys.getenv("DGRAPHS_IAN_BACKEND") if (nzchar(backend) && file.exists(backend)) { X <- rbind(c(0, 0), c(1, 0), c(2, 0), c(0, 0)) fit <- create.ian.graph(X, backend = backend, specimen.ids = c("alpha", "beta", "gamma", "delta")) stopifnot(fit$complete) graph.edges(fit$initial_graph) graph.edges(fit$final_graph) fit$mapping$member_to_profile # Four specimens, three unique profiles. fit$diagnostics$connectivity$protected.edges }# Set this variable to the path returned by build.ian.backend(). backend <- Sys.getenv("DGRAPHS_IAN_BACKEND") if (nzchar(backend) && file.exists(backend)) { X <- rbind(c(0, 0), c(1, 0), c(2, 0), c(0, 0)) fit <- create.ian.graph(X, backend = backend, specimen.ids = c("alpha", "beta", "gamma", "delta")) stopifnot(fit$complete) graph.edges(fit$initial_graph) graph.edges(fit$final_graph) fit$mapping$member_to_profile # Four specimens, three unique profiles. fit$diagnostics$connectivity$protected.edges }
For each , builds an
intersection-weighted k-NN graph and applies two pruning schemes:
(1) geometric (path-to-edge ratio) and (2) intersection-size.
Optionally performs PCA before graph construction.
create.iknn.graphs( X, k.values, max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, threshold.percentile = 0, compute.full = TRUE, 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), verbose = TRUE, knn.cache.path = NULL, knn.cache.mode = c("none", "read", "write", "readwrite") )create.iknn.graphs( X, k.values, max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, threshold.percentile = 0, compute.full = TRUE, 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), verbose = TRUE, knn.cache.path = NULL, knn.cache.mode = c("none", "read", "write", "readwrite") )
X |
A numeric matrix (or object coercible to a numeric matrix) with rows = observations and columns = features. |
k.values |
Strictly increasing integer vector of neighborhood sizes, each between 1 and n - 1. |
max.path.edge.ratio.deviation.thld |
Numeric in |
path.edge.ratio.percentile |
Numeric in |
threshold.percentile |
Numeric in |
compute.full |
Logical controlling graph-list outputs.
If |
with.isize.pruning |
Logical. If |
with.edge.pruning.stats |
Logical. If |
pca.dim |
Positive integer or |
variance.explained |
Numeric in |
knn.metric |
Character scalar specifying the geometry used for kNN search.
|
linf.tol |
Positive numeric tolerance used only when
Native graph construction is serial. |
verbose |
Logical; print progress and timing. |
knn.cache.path |
Optional character scalar path to a binary kNN cache file.
Used only when |
knn.cache.mode |
Character cache mode:
|
Geometric pruning uses the deviation threshold
max.path.edge.ratio.deviation.thld and the filtering percentile
path.edge.ratio.percentile. Intersection-size pruning currently uses
a maximum alternative path length of 2.
Output behavior by flags:
compute.full = FALSE: both geom_pruned_graphs and isize_pruned_graphs
are NULL.
compute.full = TRUE and with.isize.pruning = FALSE:
geom_pruned_graphs is returned and isize_pruned_graphs is NULL.
A list of class "iknn_graphs" with entries:
Matrix of per- edge counts and reductions.
(If the C++ side supplies column names, they’re preserved.
Otherwise we add names consistent with what the C++ returns.)
If compute.full=TRUE, list of geometrically
pruned graphs (adjacency + weights); otherwise NULL.
If compute.full=TRUE and
with.isize.pruning=TRUE, list of intersection-size pruned graphs;
otherwise NULL.
If with.edge.pruning.stats=TRUE, list (per
) of edge-level statistics; otherwise NULL.
# Generate sample data X <- matrix(rnorm(100 * 5), 100, 5) # Basic usage res1 <- create.iknn.graphs(X, k.values = seq.int(3, 10), compute.full = FALSE) # With custom pruning parameters res2 <- create.iknn.graphs(X, k.values = seq.int(3, 10), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, compute.full = TRUE, verbose = TRUE) # View statistics for each k print(res2$k_statistics)# Generate sample data X <- matrix(rnorm(100 * 5), 100, 5) # Basic usage res1 <- create.iknn.graphs(X, k.values = seq.int(3, 10), compute.full = FALSE) # With custom pruning parameters res2 <- create.iknn.graphs(X, k.values = seq.int(3, 10), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, compute.full = TRUE, verbose = TRUE) # View statistics for each k print(res2$k_statistics)
Constructs G0 with create.iknn.graphs(), then constructs G1, G2, ...,
Gm by repeatedly applying create.geodesic.iknn.graph() to each graph in
the k.values sequence. This implements the iterated nerve rule
with edge length
create.iterated.iknn.graphs( X, k.values, n.iterations = 3L, small.component = c("error", "truncate"), max.path.edge.ratio.deviation.thld = 0, path.edge.ratio.percentile = 0.5, threshold.percentile = 0, pca.dim = 100, variance.explained = 0.99, verbose = TRUE, knn.cache.path = NULL, knn.cache.mode = c("none", "read", "write", "readwrite") )create.iterated.iknn.graphs( X, k.values, n.iterations = 3L, small.component = c("error", "truncate"), max.path.edge.ratio.deviation.thld = 0, path.edge.ratio.percentile = 0.5, threshold.percentile = 0, pca.dim = 100, variance.explained = 0.99, verbose = TRUE, knn.cache.path = NULL, knn.cache.mode = c("none", "read", "write", "readwrite") )
X |
Numeric matrix with rows as observations and columns as features. |
k.values |
Strictly increasing integer vector of neighborhood sizes, each between 1 and n - 1. |
n.iterations |
Non-negative integer number of geodesic rebuilds after
|
small.component |
Component-size policy forwarded to every geodesic rebuild. |
max.path.edge.ratio.deviation.thld, path.edge.ratio.percentile, threshold.percentile
|
Initial |
pca.dim, variance.explained, verbose, knn.cache.path, knn.cache.mode
|
Additional arguments forwarded to |
A list of class "iterated_iknn_graphs" with entries:
Integer vector of requested k values.
Number of geodesic rebuilds after G0.
The "iknn_graphs" object returned by
create.iknn.graphs() for G0.
Nested list named G0, G1, ...; each entry is a named list
of graph objects for k.values.
Data frame with one row per iteration and k.
set.seed(1) X <- matrix(rnorm(30), ncol = 2) out <- create.iterated.iknn.graphs(X, k.values = seq.int(2, 3), n.iterations = 1, verbose = FALSE) out$summaryset.seed(1) X <- matrix(rnorm(30), ncol = 2) out <- create.iterated.iknn.graphs(X, k.values = seq.int(2, 3), n.iterations = 1, verbose = FALSE) out$summary
Creates a maximal packing of vertices based on a specified grid size. The algorithm places vertices in the graph using a separation distance that produces a vertex set packing of size approximately equal to the given grid size. A vertex packing is a set of vertices where each pair is separated by at least a specified distance.
create.maximal.packing( adj.list, length.list, grid.size, max.iterations = 20, precision = 0.1 )create.maximal.packing( adj.list, length.list, grid.size, max.iterations = 20, precision = 0.1 )
adj.list |
A list where each element is a vector of adjacent vertex indices (1-based) for the corresponding vertex. Must represent an undirected graph. |
length.list |
A list where each element is a vector of edge weights
corresponding to the adjacencies in |
grid.size |
A positive integer (>= 2) specifying the approximate separation distance between vertices in the packing. |
max.iterations |
Maximum number of iterations for the algorithm to converge. Default is 20. |
precision |
Precision threshold for convergence of the algorithm. Must be between 0 and 0.5. Default is 0.1. |
The function computes a maximal packing by iteratively selecting
vertices that are approximately grid.size apart from each other.
The process starts from one of the graph's diameter endpoints (determined
automatically) and continues until no more vertices can be added to the
packing without violating the distance constraint.
The returned \code{graph_diameter} represents the longest shortest path
in the graph, which provides insight into the graph's overall structure
and extent.
The \code{max_packing_radius} value indicates the minimum distance that
separates any two vertices in the packing. This value is determined
through binary search to achieve a packing of approximately the
requested size.
The function validates input parameters and ensures that the graph
structure is properly specified before computing the packing. The graph
must be undirected (symmetric adjacency) and connected.
A maximal_packing result containing its graph (a dgraph),
grid_vertices (packing indices), graph_diameter, and
max_packing_radius (the guaranteed separation of packing vertices).
validate.maximal.packing,
verify.maximal.packing
adj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) result <- create.maximal.packing(adj.list, length.list, grid.size = 2) result$grid_vertices result$max_packing_radiusadj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) result <- create.maximal.packing(adj.list, length.list, grid.size = 2) result$grid_vertices result$max_packing_radius
Creates an undirected graph where two points are connected by an edge if and only if they are present in each other's k-nearest neighbor (kNN) lists. The weight of each edge represents the distance between the connected vertices.
create.mknn.graph( X, k, prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )create.mknn.graph( X, k, prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )
X |
A numeric matrix or data frame where each row represents a data point and each column represents a feature/dimension. |
k |
A positive integer specifying the number of nearest neighbors to
consider, excluding self; require |
prune.method |
Character scalar. |
max.path.edge.ratio.deviation.thld |
Numeric scalar in |
path.edge.ratio.percentile |
Numeric scalar in |
prune.tau |
Numeric scalar greater than 1. For local geometric pruning, an edge may be removed when a retained local alternative path is at most this multiplicative factor times the direct edge length. |
prune.local.k |
Integer scalar or |
with.pruned.edge.stats |
Logical scalar. If |
connect.components |
Logical scalar. If |
connect.method |
Character scalar. |
bridge.k |
Integer scalar or |
bridge.k.max |
Integer scalar or |
bridge.growth |
Numeric scalar greater than 1. Multiplicative growth factor for ANN bridge neighborhoods. |
The mutual k-nearest neighbor graph is a symmetric graph where an edge between vertices i and j exists if and only if:
j is among the k nearest neighbors of i, AND
i is among the k nearest neighbors of j
This mutual relationship ensures that the resulting graph is undirected and typically sparser than a standard k-nearest neighbor graph.
Use graph accessors for the final graph and graph.stages() to list
stored raw, pruned and repaired stages. Construction details are in metadata.
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.
create.mknn.graphs for creating multiple graphs with different k values,
summary.mknn_graphs for summarizing graph properties
set.seed(123) X <- matrix(rnorm(60), ncol = 2) graph <- create.mknn.graph(X, k = 4) graph.order(graph) nrow(graph.edges(graph)) graph.adjacency(graph)[[1]]set.seed(123) X <- matrix(rnorm(60), ncol = 2) graph <- create.mknn.graph(X, k = 4) graph.order(graph) nrow(graph.edges(graph)) graph.adjacency(graph)[[1]]
Constructs a series of mutual k-nearest neighbor (MkNN) graphs across a range of k values, with optional geometric pruning to remove redundant edges based on alternative path analysis.
create.mknn.graphs( X, k.values, max.path.edge.ratio.thld = 1.2, path.edge.ratio.percentile = 0.5, compute.full = FALSE, pca.dim = 100, variance.explained = 0.99, verbose = FALSE )create.mknn.graphs( X, k.values, max.path.edge.ratio.thld = 1.2, path.edge.ratio.percentile = 0.5, compute.full = FALSE, pca.dim = 100, variance.explained = 0.99, verbose = FALSE )
X |
A numeric matrix where rows represent data points and columns represent features. Data frames will be converted to matrices. |
k.values |
Strictly increasing integer vector of neighborhood sizes, each between 1 and n - 1. |
max.path.edge.ratio.thld |
Maximum acceptable ratio of alternative path length to direct edge length for pruning; zero disables pruning. Edges with alternative paths having ratio <= this value will be pruned. Default is 1.2. Set to 0 to disable pruning. |
path.edge.ratio.percentile |
Percentile threshold (0.0-1.0) for edge lengths to consider for pruning. Only edges with length greater than this percentile are evaluated. Default is 0.5. |
compute.full |
Logical; if TRUE, returns complete graph structures for each k value. If FALSE, returns only summary statistics. Default is FALSE. |
pca.dim |
Maximum number of principal components to use if dimensionality reduction is applied. Default is 100. Set to NULL to skip dimensionality reduction. |
variance.explained |
Target percentage of variance to be explained by the principal components (0-1). Default is 0.99. If this can be achieved with fewer than pca.dim components, the smaller number is used. Set to NULL to use exactly pca.dim components. |
verbose |
Logical; if TRUE, displays progress messages. Default is FALSE. |
This function performs the following steps for each k value:
Mutual kNN Graph Construction: Creates a graph where edges exist only between mutually nearest neighbors.
Geometric Pruning (optional): Removes edges where alternative paths exist with acceptable length ratios. An edge (i,j) is pruned if there exists a path i->k->j such that (d(i,k) + d(k,j)) / d(i,j) <= threshold.
Dimensionality Reduction (optional): If the data has more than pca.dim dimensions, PCA is applied before graph construction to improve computational efficiency and reduce noise.
The geometric pruning step helps create sparser graphs by removing edges that can be well-approximated by two-hop paths, which can improve graph quality for clustering and visualization tasks.
An object of class "mknn_graphs" containing:
A data frame with columns: k (k value), n_edges (edges before pruning), n_edges_pruned (edges after pruning), n_removed (number of removed edges), reduction_ratio (proportion of edges removed).
If compute.full=TRUE, a named list of pruned graphs for each k value. NULL otherwise.
A list of pruning statistics for each k value, containing edge lengths and path ratios.
The returned object also has the following attributes:
k.values: The requested neighborhood sizes
max.path.edge.ratio.thld: The pruning threshold used
path.edge.ratio.percentile: The percentile threshold used
pca: If PCA was performed, contains dimensionality reduction details
create.mknn.graph for creating a single MkNN graph,
summary.mknn_graphs for summarizing the results
set.seed(123) X <- matrix(rnorm(80), ncol = 2) result <- create.mknn.graphs(X, k.values = seq.int(3, 4), compute.full = TRUE, verbose = FALSE) result$k_statistics X.high <- matrix(rnorm(120), nrow = 20, ncol = 6) result.pca <- create.mknn.graphs(X.high, k.values = seq.int(2, 3), pca.dim = 3, verbose = FALSE) attr(result.pca, "pca")$n_componentsset.seed(123) X <- matrix(rnorm(80), ncol = 2) result <- create.mknn.graphs(X, k.values = seq.int(3, 4), compute.full = TRUE, verbose = FALSE) result$k_statistics X.high <- matrix(rnorm(120), nrow = 20, ncol = 6) result.pca <- create.mknn.graphs(X.high, k.values = seq.int(2, 3), pca.dim = 3, verbose = FALSE) attr(result.pca, "pca")$n_components
Find minimum-length routes using at most each requested number of edges.
Equal-length routes prefer fewer hops. One route is stored per unordered
pair and can be retrieved in either direction with get.shortest.path().
create.path.graph(graph, h.values, stage = "final")create.path.graph(graph, h.values, stage = "final")
graph |
A |
h.values |
One or more strictly increasing positive integer hop limits. A hop counts one traversed edge. Invalid, duplicate or unordered values error; values are never silently rounded or reordered. |
stage |
Stored graph stage; defaults to |
Hop-constrained search retains a separate distance for each hop
count, then selects the best route for each pair. With nonnegative lengths,
limits above n - 1 need no additional search. For each source, auxiliary
storage is proportional to n * min(h, n - 1); storing routes for all
reachable pairs can require cubic space. Use small hop limits when possible.
A named path.graph.series collection, even for one limit. Names
are h_2, h_4, etc. Each member is a path.graph with a graph of
reachable pairs, stored shortest.paths, and an h attribute recording
the requested limit. Its graph stores route lengths and a hops edge
attribute. Routes use the input graph's vertex indices. Empty graphs and
isolated vertices are preserved.
graph <- create.graph("chain", n = 5) paths <- create.path.graph(graph, h.values = c(2, 4)) get.shortest.path(paths[["h_4"]], from = 1, to = 5) get.shortest.path(paths[["h_4"]], from = 5, to = 1) compare.paths(paths, from = 1, to = 5)graph <- create.graph("chain", n = 5) paths <- create.path.graph(graph, h.values = c(2, 4)) get.shortest.path(paths[["h_4"]], from = 1, to = 5) get.shortest.path(paths[["h_4"]], from = 5, to = 1) compare.paths(paths, from = 1, to = 5)
Create a Path Length Matrix Graph Structure
create.plm.graph(adj.list, length.list, h)create.plm.graph(adj.list, length.list, h)
adj.list |
Adjacency list using 1-based vertex indices. |
length.list |
Edge-length list matching |
h |
Odd positive integer maximum path length in hops. |
An object of class path.graph.plm.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) create.plm.graph(graph, lengths, h = 3)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) create.plm.graph(graph, lengths, h = 3)
Creates an undirected Euclidean radius graph from a numeric data matrix.
Use type = "fixed" for a fixed-radius graph, where vertices i and j
are adjacent exactly when their Euclidean distance is at most radius. Use
type = "adaptive.radius" for an adaptive-radius graph based on
observation-specific local scale distances.
create.rknn.graph( X, type = c("fixed", "adaptive.radius"), radius = NULL, k.scale = NULL, radius.factor = 1, radius.rule = c("max", "min", "geomean"), radius.search = c("ann", "all.pairs"), return.timing = FALSE, graph.detail = c("full", "minimal"), prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )create.rknn.graph( X, type = c("fixed", "adaptive.radius"), radius = NULL, k.scale = NULL, radius.factor = 1, radius.rule = c("max", "min", "geomean"), radius.search = c("ann", "all.pairs"), return.timing = FALSE, graph.detail = c("full", "minimal"), prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2 )
X |
Numeric matrix or data frame with observations in rows. |
type |
Character scalar. |
radius |
Positive numeric scalar. Edges are included when
|
k.scale |
Positive integer smaller than |
radius.factor |
Positive numeric scalar multiplying the adaptive radius. |
radius.rule |
Character scalar. |
radius.search |
Character scalar. |
return.timing |
Logical scalar. If |
graph.detail |
Character scalar. |
prune.method |
Character scalar. |
max.path.edge.ratio.deviation.thld |
Numeric scalar in |
path.edge.ratio.percentile |
Numeric scalar in |
prune.tau |
Numeric scalar greater than 1. For local geometric pruning, an edge may be removed when a retained local alternative path is at most this multiplicative factor times the direct edge length. |
prune.local.k |
Integer scalar or |
with.pruned.edge.stats |
Logical scalar. If |
connect.components |
Logical scalar. If |
connect.method |
Character scalar. |
bridge.k |
Integer scalar or |
bridge.k.max |
Integer scalar or |
bridge.growth |
Numeric scalar greater than 1. Multiplicative growth factor for ANN bridge neighborhoods. |
A dgraph, with constructor class radius_graph for fixed radii
or adaptive_radius_graph for adaptive radii. Use graph accessors for
topology, lengths and retained stages; construction diagnostics are in
metadata.
X <- matrix(c(0, 1, 3), ncol = 1) as.matrix(graph.edges(create.rknn.graph(X, type = "fixed", radius = 1.1))[, c("from", "to")]) as.matrix(graph.edges(create.rknn.graph(X, type = "adaptive.radius", k.scale = 1))[, c("from", "to")])X <- matrix(c(0, 1, 3), ncol = 1) as.matrix(graph.edges(create.rknn.graph(X, type = "fixed", radius = 1.1))[, c("from", "to")]) as.matrix(graph.edges(create.rknn.graph(X, type = "adaptive.radius", k.scale = 1))[, c("from", "to")])
Creates a sequence of adaptive-radius graphs by varying the k.scale
parameter passed to create.rknn.graph(type = "adaptive.radius"). By
default, ANN-backed construction uses the batched C++ backend while the
direct all-pairs reference path uses the scalar R loop. Set backend = "r"
to force the scalar loop for ANN parity checks.
create.rknn.graphs(X, k.values, ..., backend = c("auto", "cpp", "r"))create.rknn.graphs(X, k.values, ..., backend = c("auto", "cpp", "r"))
X |
Numeric matrix or data frame with observations in rows. |
k.values |
Strictly increasing integer vector, each between 1 and n - 1. Returned graphs follow this order. |
... |
Additional arguments forwarded to |
backend |
Character scalar. |
A list of class "rknn_graphs" with components:
A named list of adaptive-radius graph objects, one per k.
A data frame with one row per k containing edge, component, and MST-repair counts.
Present only when forwarded options request graph timing; contains backend-specific construction timing rows.
Attributes include k.values and n_vertices.
X <- matrix(c(0, 1, 3, 4), ncol = 1) result <- create.rknn.graphs(X, k.values = seq.int(1, 2), radius.search = "all.pairs", graph.detail = "minimal", prune.method = "none") names(result$graphs) result$k_statisticsX <- matrix(c(0, 1, 3, 4), ncol = 1) result <- create.rknn.graphs(X, k.values = seq.int(1, 2), radius.search = "all.pairs", graph.detail = "minimal", prune.method = "none") names(result$graphs) result$k_statistics
Creates 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.
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") )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") )
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 |
prune.method |
Character scalar. |
prune.tau |
Numeric scalar greater than 1, or |
prune.local.k |
Integer scalar or |
path.edge.ratio.percentile |
Numeric in |
threshold.percentile |
Numeric in |
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.
|
linf.tol |
Positive numeric tolerance used only when
|
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 |
connect.method |
Character scalar. |
bridge.k |
Integer scalar or NULL. Initial ANN bridge neighborhood size
for |
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
|
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 |
Character cache mode:
|
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.
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.
# Create sample data set.seed(123) X <- matrix(rnorm(100), ncol = 2) result <- create.single.iknn.graph(X, k = 3) summary(result)# Create sample data set.seed(123) X <- matrix(rnorm(100), ncol = 2) result <- create.single.iknn.graph(X, k = 3) summary(result)
Creates an undirected symmetric k-nearest neighbor (sKNN) graph from a numeric
data matrix. An edge between vertices i and j is present when either
j is among the k nearest neighbors of i, or i is among the k
nearest neighbors of j.
create.sknn.graph( X, k, prune.edges = FALSE, prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), edge.weight = c("distance"), neighbor.method = c("exact", "ann"), ann.eps = 0, knn.index = NULL, graph.detail = c("full", "minimal"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2, input.type = c("observations", "distances") )create.sknn.graph( X, k, prune.edges = FALSE, prune.method = c("none", "local.geodesic", "global.geodesic.ratio"), max.path.edge.ratio.deviation.thld = 0.1, path.edge.ratio.percentile = 0.5, prune.tau = 1.05, prune.local.k = NULL, with.pruned.edge.stats = FALSE, connect.components = FALSE, connect.method = c("component.mst", "component.mst.ann", "global.mst"), edge.weight = c("distance"), neighbor.method = c("exact", "ann"), ann.eps = 0, knn.index = NULL, graph.detail = c("full", "minimal"), bridge.k = NULL, bridge.k.max = NULL, bridge.growth = 2, input.type = c("observations", "distances") )
X |
Numeric observation matrix/data frame, or a symmetric numeric distance
matrix or |
k |
Integer scalar. Number of non-self nearest neighbors. |
prune.edges |
Logical scalar. If |
prune.method |
Character scalar. |
max.path.edge.ratio.deviation.thld |
Numeric scalar in |
path.edge.ratio.percentile |
Numeric scalar in |
prune.tau |
Numeric scalar greater than 1. An edge may be pruned when the shortest retained local alternative path is at most this multiplicative factor times the direct edge length. |
prune.local.k |
Integer scalar or |
with.pruned.edge.stats |
Logical scalar. If |
connect.components |
Logical scalar. If |
connect.method |
Character scalar. |
edge.weight |
Character scalar. Currently only |
neighbor.method |
Character scalar. |
ann.eps |
Non-negative numeric scalar reserved for approximate ANN
search. Currently only |
knn.index |
Optional integer matrix of precomputed, one-based, ordered
non-self neighbor indices. It must have |
graph.detail |
Character scalar. |
bridge.k |
Integer scalar or |
bridge.k.max |
Integer scalar or |
bridge.growth |
Numeric scalar greater than 1. Multiplicative growth factor for bridge candidate neighborhoods. |
input.type |
Input interpretation. Defaults to |
With input.type = "distances", supplied distances determine exact neighbor
rankings, every edge length, and component/global MST repair. Distance input
must be finite, nonnegative, square and symmetric, with a zero diagonal.
Symmetry and diagonal tolerance is 1e-12 * max(1, max(X)); accepted
asymmetry is averaged and the diagonal set to zero. Row and column names,
if present, must be identical and unique. Off-diagonal zeros are allowed.
Triangle inequality is not tested, so symmetric dissimilarities are accepted.
Ties are resolved by increasing vertex index, excluding self explicitly.
ANN search/repair and pruning are unsupported for distance input and error.
The series constructor validates distances and ranks neighbors once, through
its largest requested k. Full lifecycle stages use these same distances.
With no nearest-neighbor ties, the sKNN edge rule is equivalent to
where is the distance from point to its k-th
non-self nearest neighbor.
If connect.components = TRUE, the graph is augmented with MST edges. The
default connect.method = "component.mst" first collapses each connected
component of the sKNN graph to one component vertex, weights each component
pair by the shortest data-space edge between them, and adds the minimum
spanning tree of this component graph. This adds exactly m - 1 bridge
edges when the original sKNN graph has m connected components.
connect.method = "component.mst.ann" uses ANN nearest-neighbor bridge
candidates first and automatically falls back to exact component MST when
the sparse candidate graph does not connect all components. The alternative
connect.method = "global.mst" unions the sKNN graph with the full
Euclidean MST on the data points.
neighbor.method = "exact" computes all pairwise distances and is the
deterministic reference implementation. neighbor.method = "ann" uses
the bundled ANN kd-tree for the Euclidean kNN search step; exact parity can
differ only in nearest-neighbor tie cases. Edge weights are always returned
as ordinary Euclidean distances. Exact component.mst repair uses exact
pairwise bridge distances; component.mst.ann uses ANN bridge candidates
before guaranteed exact fallback.
If prune.method = "local.geodesic" or prune.edges = TRUE, an
experimental local-geodesic pruning stage is applied after the sKNN support
is built and before optional MST connectivity repair. Candidate edges are
processed longest-first. For an edge (i, j), the edge is removed only when
the currently retained graph contains an alternative path from i to j,
restricted to the union of their local neighborhoods, whose length is at most
prune.tau times the direct edge length. prune.method = "global.geodesic.ratio" instead uses the whole graph as the alternative-path
search domain and removes long edges whose shortest alternative path is
within the configured geodesic-ratio threshold.
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.
X <- rbind(c(0, 0), c(1, 0), c(10, 0), c(11, 0)) g <- create.sknn.graph(X, k = 1, connect.components = TRUE) g$metadata$n_components_before g$metadata$n_components_after g$metadata$mst_edge_matrixX <- rbind(c(0, 0), c(1, 0), c(10, 0), c(11, 0)) g <- create.sknn.graph(X, k = 1, connect.components = TRUE) g$metadata$n_components_before g$metadata$n_components_after g$metadata$mst_edge_matrix
Constructs symmetric k-nearest neighbor graphs for several values of k
while performing one bundled ANN search for observations, or one exact
ranking of supplied distances, at the largest requested value. The
ordered non-self neighbor matrix is sliced for each graph, so lower-k graphs
use exactly the same neighbor ranking as the largest graph.
create.sknn.graphs( X, k.values, ..., input.type = c("observations", "distances") )create.sknn.graphs( X, k.values, ..., input.type = c("observations", "distances") )
X |
Numeric observation matrix/data frame, or a symmetric numeric distance
matrix or |
k.values |
Strictly increasing integer vector of neighborhood sizes, each between 1 and n - 1. |
... |
Named arguments forwarded to |
input.type |
Input interpretation. Defaults to |
A list of class "sknn_graphs" with components graphs, a named
list of "sknn_graph" objects, and k_statistics, a data frame of edge
and component counts. Attributes record the requested values and number of
vertices.
set.seed(1) X <- matrix(rnorm(60), ncol = 3) graphs <- create.sknn.graphs( X, k.values = c(2, 4), graph.detail = "minimal" ) graphs$k_statisticsset.seed(1) X <- matrix(rnorm(60), ncol = 3) graphs <- create.sknn.graphs( X, k.values = c(2, 4), graph.detail = "minimal" ) graphs$k_statistics
Extract an Induced Subgraph
create.subgraph(graph, vertices, stage = "final")create.subgraph(graph, vertices, stage = "final")
graph |
A |
vertices |
Unique vertex indices, in the desired output order. |
stage |
Stored stage to extract. |
A dgraph with compact indices and aligned lengths and attributes.
metadata$original.vertices maps its vertices back to the original graph.
graph <- create.graph("chain", 4) sub <- create.subgraph(graph, vertices = c(4, 3)) graph.edges(sub) sub$metadata$original.verticesgraph <- create.graph("chain", 4) sub <- create.subgraph(graph, vertices = c(4, 3)) graph.edges(sub) sub$metadata$original.vertices
Create a Threshold Distance Graph
create.threshold.distance.graph(dist.matrix, threshold, include.names = TRUE)create.threshold.distance.graph(dist.matrix, threshold, include.names = TRUE)
dist.matrix |
Symmetric distance matrix. |
threshold |
Numeric distance threshold. Vertices with distance less than this value are connected. |
include.names |
Logical; if |
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.
distances <- as.matrix(dist(matrix(c(0, 1, 3), ncol = 1))) create.threshold.distance.graph(distances, threshold = 1.5)distances <- as.matrix(dist(matrix(c(0, 1, 3), ncol = 1))) create.threshold.distance.graph(distances, threshold = 1.5)
Detects terminal arm tips in a graph by:
computing graph endpoint scores from the 3D embedding,
optionally smoothing those scores on the graph using
fit.rdgraph.regression() and refit.rdgraph.regression(),
finding graph-local maxima with detect.local.extrema(),
retaining only maxima that persist across neighborhood scales.
The function works with terminal regions in an embedding; returned endpoints need not be degree-1 vertices.
detect.graph.endpoints( adj.list, length.list, layout.3d, neighborhood = c("geodesic_k", "geodesic_radius"), k = c(10L, 20L, 30L), radius = NULL, q = 0.1, neighbor.weighting = c("uniform", "inverse_distance", "gaussian"), gaussian.sigma = NULL, min.neighborhood.size = 3L, scale.aggregate = c("mean", "median", "min", "max"), score.metric = c("score", "m", "s.q", "s.min"), smooth = FALSE, fitted.model = NULL, smooth.fit.args = NULL, smooth.refit.args = NULL, detect.max.radius = 2, detect.min.neighborhood.size = 2L, scale.stability.radius = NULL, min.scale.stability = 0.5, min.score.quantile = 0.8, max.endpoints = NULL, verbose = FALSE )detect.graph.endpoints( adj.list, length.list, layout.3d, neighborhood = c("geodesic_k", "geodesic_radius"), k = c(10L, 20L, 30L), radius = NULL, q = 0.1, neighbor.weighting = c("uniform", "inverse_distance", "gaussian"), gaussian.sigma = NULL, min.neighborhood.size = 3L, scale.aggregate = c("mean", "median", "min", "max"), score.metric = c("score", "m", "s.q", "s.min"), smooth = FALSE, fitted.model = NULL, smooth.fit.args = NULL, smooth.refit.args = NULL, detect.max.radius = 2, detect.min.neighborhood.size = 2L, scale.stability.radius = NULL, min.scale.stability = 0.5, min.score.quantile = 0.8, max.endpoints = NULL, verbose = FALSE )
adj.list |
Graph adjacency list (1-based vertex indices). |
length.list |
Edge-length list aligned with |
layout.3d |
Numeric matrix or data frame with 3 columns giving the 3D embedding coordinates for graph vertices. |
neighborhood |
Character string. Either |
k |
Integer vector of geodesic neighborhood sizes used when
|
radius |
Positive numeric vector of geodesic radii used when
|
q |
Quantile used for |
neighbor.weighting |
Character string controlling neighbor weights for
|
gaussian.sigma |
Optional positive numeric scale used when
|
min.neighborhood.size |
Minimum number of usable neighbors required after removing zero-length embedding vectors. |
scale.aggregate |
How to aggregate scores across multiple neighborhood
scales. One of |
score.metric |
Which score to maximize. One of |
smooth |
Logical; if |
fitted.model |
Optional fitted graph smoother from
|
smooth.fit.args |
Optional named list of arguments passed to
|
smooth.refit.args |
Optional named list of arguments passed to
|
detect.max.radius |
Maximum radius passed to |
detect.min.neighborhood.size |
Minimum neighborhood size passed to
|
scale.stability.radius |
Optional non-negative geodesic radius used when
translating per-scale local maxima into multiscale support. If |
min.scale.stability |
Minimum fraction of scales for which a vertex must
be a local maximum of the per-scale detection score to be retained as an
endpoint. Default is |
min.score.quantile |
Quantile filter applied to the final detection
score before returning endpoints. Default is |
max.endpoints |
Optional positive integer cap on returned endpoints. |
verbose |
Logical; if |
A list with endpoint vertices, score diagnostics, optional smoothed scores, scale stability summaries, and the local-extrema fit used for endpoint calling.
chain <- create.graph("chain", n = 8) layout <- cbind(seq_len(8), 0, 0) endpoints <- detect.graph.endpoints(graph.adjacency(chain), graph.lengths(chain), layout, k = c(2, 3), min.neighborhood.size = 2, detect.max.radius = 2, detect.min.neighborhood.size = 2, min.score.quantile = 0.5) endpoints$endpointschain <- create.graph("chain", n = 8) layout <- cbind(seq_len(8), 0, 0) endpoints <- detect.graph.endpoints(graph.adjacency(chain), graph.lengths(chain), layout, k = c(2, 3), min.neighborhood.size = 2, detect.max.radius = 2, detect.min.neighborhood.size = 2, min.score.quantile = 0.5) endpoints$endpoints
Detect Local Extrema in a Graph
detect.local.extrema( adj.list, length.list, y, max.radius, min.neighborhood.size, detect.maxima = TRUE, custom.prefix = NULL )detect.local.extrema( adj.list, length.list, y, max.radius, min.neighborhood.size, detect.maxima = TRUE, custom.prefix = NULL )
adj.list |
Graph adjacency list using 1-based vertex indices. |
length.list |
Edge-length list aligned with |
y |
Numeric vertex function values. |
max.radius |
Maximum graph-geodesic radius for neighborhoods. |
min.neighborhood.size |
Minimum neighborhood size required. |
detect.maxima |
Logical; if |
custom.prefix |
Optional label prefix. |
Summaries use the recorded detection setting for empty results. Empty objects
saved by older versions lack this setting; their summaries report NA for
the extrema type because it cannot be recovered from empty vectors.
A local_extrema object. Its scalar logical detect.maxima component
records whether maxima or minima were requested, even when no extrema are
found. The per-extremum is_maxima and type vectors are empty in that case.
chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) extrema$verticeschain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) extrema$vertices
A dgraph stores an undirected simple graph, including isolated vertices.
Adjacency, lengths and scalar edge attributes are validated together and
sorted together. Zero lengths are edges; absent lengths remain NULL.
dgraph(adj.list, length.list = NULL, edge.attributes = list()) graph.adjacency(graph, stage = "final") graph.lengths(graph, stage = "final") graph.order(graph) graph.stages(graph) graph.edge.attribute(graph, name, stage = "final") graph.edges(graph, stage = "final")dgraph(adj.list, length.list = NULL, edge.attributes = list()) graph.adjacency(graph, stage = "final") graph.lengths(graph, stage = "final") graph.order(graph) graph.stages(graph) graph.edge.attribute(graph, name, stage = "final") graph.edges(graph, stage = "final")
adj.list |
List of 1-based neighbor vectors, one per vertex. |
length.list |
Optional aligned finite nonnegative numeric length lists. |
edge.attributes |
Named list of aligned scalar edge-attribute lists. |
graph |
A |
stage |
Stored graph stage; defaults to |
name |
Name of a stored edge attribute, for example |
dgraph() returns a graph. The accessors return adjacency lists,
length lists (or NULL), an ordered edge data frame, the vertex count,
stage names, or the requested attribute list, respectively. Edge tables
contain integer from < to, optional numeric length, and attributes.
graph <- dgraph(list(c(3L, 2L), 1L, 1L, integer()), list(c(0, 2), 2, 0, numeric())) graph.order(graph) graph.edges(graph) graph.stages(graph) graph.adjacency(graph) graph.lengths(graph)graph <- dgraph(list(c(3L, 2L), 1L, 1L, integer()), list(c(0, 2), 2, 0, numeric())) graph.order(graph) graph.edges(graph) graph.stages(graph) graph.adjacency(graph) graph.lengths(graph)
Compute Edge Difference Between Two Graphs
edge.diff(adj.list1, adj.list2)edge.diff(adj.list1, adj.list2)
adj.list1 |
First adjacency list. |
adj.list2 |
Second adjacency list. |
A list containing neighbors present in graph1 but not graph2 for
each vertex.
graph1 <- list(c(2L, 3L), 1L, 1L) graph2 <- list(2L, 1L, integer(0)) edge.diff(graph1, graph2)graph1 <- list(c(2L, 3L), 1L, 1L) graph2 <- list(2L, 1L, integer(0)) edge.diff(graph1, graph2)
For quadforms this integrates the induced metric along each straight latent segment. Flat quadforms reduce exactly to Euclidean distance.
edge.lengths.synthetic.geometry(geometry, from, to, tolerance = 1e-10)edge.lengths.synthetic.geometry(geometry, from, to, tolerance = 1e-10)
geometry |
A |
from, to
|
Matching endpoint matrices with one segment per row. |
tolerance |
Positive integration tolerance. |
A numeric vector of segment lengths.
geometry <- synthetic.quadform(1L, 1L) edge.lengths.synthetic.geometry(geometry, matrix(0), matrix(2))geometry <- synthetic.quadform(1L, 1L) edge.lengths.synthetic.geometry(geometry, matrix(0), matrix(2))
Lift coordinates onto a quadratic surface using Geometry Lab arithmetic
embed.quadform.surface(latent, coefficients)embed.quadform.surface(latent, coefficients)
latent |
Finite numeric matrix with two columns. |
coefficients |
Three finite coefficients for u^2, 2uv and v^2. |
A three-column matrix. Version-1 arithmetic preserves existing Geometry Lab cloud identities and reference meshes.
embed.quadform.surface(matrix(c(0, 1, 0, 1), ncol = 2), c(1, 0, -1))embed.quadform.surface(matrix(c(0, 1, 0, 1), ncol = 2), c(1, 0, -1))
This deterministic operator performs no random draws. A realized
frame.matrix is required for random-frame geometries.
embed.synthetic.geometry(geometry, latent, frame.matrix = NULL)embed.synthetic.geometry(geometry, latent, frame.matrix = NULL)
geometry |
A synthetic geometry component. |
latent |
Latent coordinates in rows. |
frame.matrix |
Optional realized orthonormal frame. |
A numeric matrix of observed coordinates.
geometry <- synthetic.circle() embed.synthetic.geometry(geometry, matrix(c(0, pi / 2), ncol = 1))geometry <- synthetic.circle() embed.synthetic.geometry(geometry, matrix(c(0, pi / 2), ncol = 1))
Explore saved data-geodesic graph reconstruction benchmarks using manual graph selection, metric-based selection, saved layouts and parameter scans. This is the maintained replacement for the dggraphui application.
explore.graphs( project = NULL, launch = TRUE, host = "127.0.0.1", port = getOption("shiny.port"), launch.browser = interactive(), ... )explore.graphs( project = NULL, launch = TRUE, host = "127.0.0.1", port = getOption("shiny.port"), launch.browser = interactive(), ... )
project |
Optional benchmark directory, benchmark manifest file, or
name previously stored by |
launch |
If |
host |
Interface on which to listen; defaults to the local computer. |
port |
Optional port passed to |
launch.browser |
Whether to open the browser when launching. |
... |
Further arguments to |
The optional packages shiny, bslib, plotly and digest are required only for the explorer. The optional grip package is needed only when explicitly generating a missing weighted layout. Opening a project reads saved results; it does not reconstruct graphs, fit layouts or overwrite benchmark assets. Newly generated layouts are stored in a separate dgraphs user cache.
Project registration stores locations in the user's dgraphs data directory,
outside the installed package. Set options(dgraphs.projects_dir = ...)
to choose another catalog directory. Set
options(dgraphs.graph_explorer_cache_dir = ...) to choose the layout cache.
The default display preserves original coordinates and equal x/y/z units. Optional centering with a single scale factor preserves proportions. Per-axis normalization is labeled as distorting proportions. The displayed edge count discloses thinning above 4000 edges; saved metrics always use the complete graph and are never recomputed by display controls.
Choose Open circle demo in the app, or use the installed project below. Its two chord-weighted graphs use 12 equally spaced unit-circle points. Increasing k from 2 to 4 introduces shortcuts relative to exact shorter circle arcs. Layouts and metrics are already saved; no fitting is needed.
When launch = FALSE, a shiny.appobj; otherwise the result of
shiny::runApp(), invisibly.
read.graph.benchmark(), register.graph.project()
if (interactive() && all(vapply(c("shiny", "bslib", "plotly", "digest"), requireNamespace, logical(1), quietly = TRUE))) { demo <- system.file("extdata", "graph-explorer-demo", package = "dgraphs") explore.graphs(demo) }if (interactive() && all(vapply(c("shiny", "bslib", "plotly", "digest"), requireNamespace, logical(1), quietly = TRUE))) { demo <- system.file("extdata", "graph-explorer-demo", package = "dgraphs") explore.graphs(demo) }
Extract Edge Lengths Along a Graph Path
extract.trajectory.edge.lengths( traj, adj.list, length.list, add.quantiles = FALSE )extract.trajectory.edge.lengths( traj, adj.list, length.list, add.quantiles = FALSE )
traj |
Numeric or integer vector of consecutive graph vertices. |
adj.list |
Adjacency list. |
length.list |
Edge-length list aligned with |
add.quantiles |
Logical; if |
Data frame with consecutive vertex pairs and their edge lengths.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) extract.trajectory.edge.lengths(c(1, 2, 3), graph, lengths)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) extract.trajectory.edge.lengths(c(1, 2, 3), graph, lengths)
Minimize sums of powered edge lengths. Coordinate input defaults to the complete Euclidean graph, implementing the sample Fermat distance on the observed points. A symmetric kNN restriction or a supplied graph is an explicit alternative, with no automatic guarantee of the same distances.
fermat.distances( graph = NULL, p = 2, rooted = FALSE, vertices = NULL, stage = "final", points = NULL, graph.type = NULL, k = NULL, backend = "explicit", sources = NULL, targets = NULL, max.workspace.bytes = 512 * 1024^2, return.graph = FALSE )fermat.distances( graph = NULL, p = 2, rooted = FALSE, vertices = NULL, stage = "final", points = NULL, graph.type = NULL, k = NULL, backend = "explicit", sources = NULL, targets = NULL, max.workspace.bytes = 512 * 1024^2, return.graph = FALSE )
graph |
A |
p |
Finite numeric scalar at least one; the edge-length exponent. |
rooted |
Logical scalar. If |
vertices |
Optional unique 1-based vertex indices in output order.
Paths may use all vertices. |
stage |
Stored graph stage, default |
points |
Finite numeric matrix or data frame, observations in rows. |
graph.type |
Coordinate construction: |
k |
Required for |
backend |
Complete-graph coordinate backend: |
sources |
Optional unique source indices for rectangular queries with
|
targets |
Optional unique target indices with |
max.workspace.bytes |
Positive finite workspace allowance for the implicit backend (default 512 MiB). The estimate includes coordinates, output and linear native scratch, not total R process memory or R copies. |
return.graph |
Logical scalar; return distances together with the union
of selected shortest-path edges and coverage metadata. Defaults to |
For base lengths , the unrooted result is
. At p = 1, complete-graph coordinate
distances are Euclidean; restricted distances are ordinary graph distances.
Restricting edges cannot decrease the result when retained weights agree.
Taking k = n - 1 recovers the complete graph.
Groisman, Jonckheere and Sapienza define the unrooted complete-graph
estimator and prove consistency after sample-size normalization under
their sampling assumptions. Their Proposition 2.12 establishes a
high-probability equality for a sufficiently large nearest-neighbor
restriction under its stated assumptions. It does not certify arbitrary
fixed k, pruned graphs, or arbitrary supplied lengths. This function
applies neither sample-size normalization nor an estimated limit constant.
Both coordinate constructions evaluate all Euclidean pairs. Explicit
complete graphs store quadratic adjacency. The implicit backend uses dense
Dijkstra searches with linear scratch and no graph restriction: with h
sources, n observations and d coordinates its worst-case time is O(hn^2d).
A global numeric-range check takes O(n^2d) time. Pivot-to-all output uses
O(hn) storage; full all-pairs output is still quadratic. Select pivots
outside this function; no automatic pivot sampling or distance approximation
is performed. Distances are computed in floating-point arithmetic.
Overflow, positive powered lengths underflowing to zero, and a conservative
upper bound on simple-path cost exceeding the numeric range cause errors;
rescale base lengths before retrying. Multiplying lengths by a > 0
multiplies unrooted distances by a^p (rooted distances by a).
With return.graph = TRUE, one deterministic shortest-path tree is selected
per source (ties need not include every minimizing path). Only paths to the
requested targets contribute edges. The returned graph retains all input
vertices, including unused isolated vertices. Its edge lengths are powered
base lengths even when the returned distances are rooted. Thus graph
geodesics reproduce the unrooted requested distances. With all sources and
targets it preserves every pair; a subset guarantees only the requested
pairs. The union need not be sparse. The implicit workspace estimate includes
a conservative allowance for the predecessor-edge union when requested.
Numeric square distance matrix, or a source-by-target matrix when
sources is supplied, in requested order. Unreachable
pairs are Inf. Zero-length edges are retained; duplicate points have zero
distance. Point row names or graph adjacency names label the matrix.
With return.graph = TRUE, return a list containing distances (this
matrix), graph (a dgraph with powered base edge lengths), and metadata.
Metadata records sources, targets, coverage (all_pairs or
requested_pairs), p, rooted, edge.weight.type, and the backend used.
Graph distances are unrooted even when the returned matrix is rooted.
Groisman, P., Jonckheere, M. and Sapienza, F. (2022). Nonhomogeneous Euclidean first-passage percolation and distance learning. Bernoulli, 28(1), 255–276. doi:10.3150/21-BEJ1341. See Definitions 2.1 and 2.11 and Proposition 2.12 in https://arxiv.org/html/1810.09398v2.
graph.geodesic.distances(), create.sknn.graph()
X <- matrix(c(0, 1, 2), ncol = 1) fermat.distances(points = X, p = 2) # 0 -> 1 -> 2 costs 2, not 4 fermat.distances(points = X, p = 2, rooted = TRUE) fermat.distances(points = X, graph.type = "sknn", k = 1) g <- dgraph(list(2L, c(1L, 3L), 2L), list(1, c(1, 1), 1)) fermat.distances(g, vertices = c(1, 3))X <- matrix(c(0, 1, 2), ncol = 1) fermat.distances(points = X, p = 2) # 0 -> 1 -> 2 costs 2, not 4 fermat.distances(points = X, p = 2, rooted = TRUE) fermat.distances(points = X, graph.type = "sknn", k = 1) g <- dgraph(list(2L, c(1L, 3L), 2L), list(1, c(1, 1), 1)) fermat.distances(g, vertices = c(1, 3))
Find nearest neighbors in the complete-graph sample Fermat distance using Euclidean neighbor pruning and truncated Dijkstra searches.
fermat.knn(points, k, p = 2, rooted = FALSE, algorithm = "kd_tree") create.fermat.sknn.graph( points, k, p = 2, rooted = FALSE, algorithm = "kd_tree" )fermat.knn(points, k, p = 2, rooted = FALSE, algorithm = "kd_tree") create.fermat.sknn.graph( points, k, p = 2, rooted = FALSE, algorithm = "kd_tree" )
points |
Finite numeric matrix or data frame, observations in rows. |
k |
Number of other observations to return per row; |
p |
Finite edge-length exponent at least one. |
rooted |
Logical; return the |
algorithm |
Exact Euclidean search algorithm passed to |
The unrooted distance is the minimum sum of Euclidean edge lengths
raised to p, allowing paths through all observations. Rooting preserves
neighbor rankings. Lemma 5.6 of McKenzie and Damelin justifies pruning to
directed Euclidean neighbor lists for nearest-neighbor queries. This does
not establish equality of all pairwise distances on the sparse graph.
The paper counts the source among its neighbors; here k excludes it.
Equal-distance neighbors at the cutoff may be selected arbitrarily; their identities need not agree across search algorithms or permutations. Duplicate observations are retained as distinct vertices with zero distance. Exactness refers to the complete-graph target, subject to floating-point arithmetic. Extremely disparate coordinate scales should be rescaled. Nonfinite computed lengths and powered costs, and positive costs that underflow to zero, cause errors.
Candidate lists and output use O(nk) storage. After Euclidean search, binary-heap path searches take O(nk^2*log(k+1)) time with O(n+k^2) scratch. Euclidean search may be quadratic in n in high dimensions. Unlike the implicit distance backend, this function does not scan every complete-graph edge for numeric-range validation.
fermat.knn() returns a list with n-by-k matrices index (1-based
neighbor indices) and distance (in nondecreasing order), excluding self.
create.fermat.sknn.graph() returns a dgraph formed by the union of these
directed selections. Its lengths are Fermat distances, not powered direct
Euclidean edges. Vertex degrees can exceed k; components are not repaired.
Use graph.geodesic.distances() to sum stored lengths, rather than applying
fermat.distances() with p > 1 and powering them again.
McKenzie, D. and Damelin, S. (2019). Power Weighted Shortest Paths for Clustering Euclidean Data. Section 5, Lemma 5.6 and Algorithm 2. https://arxiv.org/abs/1905.13345.
fermat.distances(), create.sknn.graph()
X <- cbind(c(0, 1, 2, 4), 0) fermat.knn(X, k = 2, p = 2) graph <- create.fermat.sknn.graph(X, k = 2) graph.edges(graph)X <- cbind(c(0, 1, 2, 4), 0) fermat.knn(X, k = 2, p = 2) graph <- create.fermat.sknn.graph(X, k = 2) graph.edges(graph)
Select Graph Endpoints by Core-Eccentricity Geometry
geodesic.core.endpoints( adj.list, length.list, core.quantile = 0.1, endpoint.quantile = 0.9, use.approx.eccentricity = TRUE, n.landmarks = 64L, max.endpoints = NULL, seed = 1L, verbose = FALSE )geodesic.core.endpoints( adj.list, length.list, core.quantile = 0.1, endpoint.quantile = 0.9, use.approx.eccentricity = TRUE, n.landmarks = 64L, max.endpoints = NULL, seed = 1L, verbose = FALSE )
adj.list |
Graph adjacency list using 1-based vertex indices. |
length.list |
Edge-length list aligned with |
core.quantile |
Numeric in |
endpoint.quantile |
Numeric in |
use.approx.eccentricity |
Use landmark-based eccentricity approximation. |
n.landmarks |
Number of landmarks when approximation is used. |
max.endpoints |
Optional positive cap on returned endpoints. |
seed |
Integer seed for landmark initialization. |
verbose |
Print backend progress. |
A geodesic_core_endpoints list of endpoints and diagnostics.
graph <- create.graph("chain", n = 8) endpoints <- geodesic.core.endpoints(graph.adjacency(graph), graph.lengths(graph), use.approx.eccentricity = FALSE) endpoints$endpointsgraph <- create.graph("chain", n = 8) endpoints <- geodesic.core.endpoints(graph.adjacency(graph), graph.lengths(graph), use.approx.eccentricity = FALSE) endpoints$endpoints
Geodesic Disk in a Weighted Graph
geodesic.disk(adj.list, length.list, center.vertex, radius = NULL, n = NULL)geodesic.disk(adj.list, length.list, center.vertex, radius = NULL, n = NULL)
adj.list |
Adjacency list. |
length.list |
Edge-length list aligned with |
center.vertex |
Center vertex. |
radius |
Optional geodesic radius. |
n |
Optional target number of reachable vertices. |
List with vertices, effective radius, and aligned dists.
graph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) geodesic.disk(graph, weights, center.vertex = 2, radius = 2)graph <- list(2L, c(1L, 3L), 2L) weights <- list(1, c(1, 2), 2) geodesic.disk(graph, weights, center.vertex = 2, radius = 2)
Find Geodesic Neighbors Within a Point Cloud
geodesic.knn( X, k, k.graph = 5, graph = NULL, small.component = c("error", "truncate") )geodesic.knn( X, k, k.graph = 5, graph = NULL, small.component = c("error", "truncate") )
X |
Finite numeric matrix of observations, one per row. |
k |
Number of other vertices to return, an integer in |
k.graph |
Number of other neighbors used to construct the auxiliary
symmetric kNN graph. Components are not automatically connected.
Ignored when |
graph |
Optional |
small.component |
Error if fewer than |
A list with nn.index and nn.dist matrices with k columns and
effective.k, the number returned per row. Under explicit truncation,
absent indices and distances are NA; unreachable vertices are never
reported as neighbors.
geodesic.knnx(), graph.geodesic.distances()
X <- cbind(0:3, 0) geodesic.knn(X, k = 1, k.graph = 1) # one other vertex per rowX <- cbind(0:3, 0) geodesic.knn(X, k = 1, k.graph = 1) # one other vertex per row
Find Geodesic Neighbors from Grid Queries to Observations
geodesic.knnx( X, X.grid, k, k.graph = 5, small.component = c("error", "truncate") )geodesic.knnx( X, X.grid, k, k.graph = 5, small.component = c("error", "truncate") )
X |
Finite numeric matrix of data observations. |
X.grid |
Finite numeric matrix of grid query points, with the same
number of coordinate columns as |
k |
Number of data observations returned per grid query, in |
k.graph |
Number of grid vertices attached to each observation, in
|
small.component |
Error on insufficient reachable observations, or
explicitly |
A list with combined coordinates V (grid rows first), edge pairs
E in V row indices, nn.index (indices into X), nn.dist and
effective.k (the number returned per grid query).
X.grid <- as.matrix(expand.grid(x = 0:2, y = 0:2)) X <- rbind(c(0, 0), c(1.2, 0.8), c(1.8, 1.7)) geodesic.knnx(X, X.grid, k = 2)X.grid <- as.matrix(expand.grid(x = 0:2, y = 0:2)) X <- rbind(c(0, 0), c(1.2, 0.8), c(1.8, 1.7)) geodesic.knnx(X, X.grid, k = 2)
Get Shortest Path Between Two Vertices
get.shortest.path(path.result, from, to)get.shortest.path(path.result, from, to)
path.result |
A |
from |
Source vertex. |
to |
Target vertex. |
A list with path (vertex indices in requested direction), length
and hops, or NULL when no stored route exists within this result's
hop limit. A vertex queried against itself has path from, length zero
and zero hops. Routes can be retrieved in either direction.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) pg <- create.path.graph(dgraph(graph, lengths), h.values = 2)[[1L]] get.shortest.path(pg, from = 1, to = 3)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) pg <- create.path.graph(dgraph(graph, lengths), h.values = 2)[[1L]] get.shortest.path(pg, from = 1, to = 3)
Assign Vertices to Connected Components
graph.connected.components(graph, stage = "final")graph.connected.components(graph, stage = "final")
graph |
A |
stage |
Stored graph stage. |
Integer vector of component IDs, one per vertex.
graph <- dgraph(list(2L, 1L, integer())) graph.connected.components(graph)graph <- dgraph(list(2L, 1L, integer())) graph.connected.components(graph)
Embed Graph in 2D or 3D Space
graph.embedding( graph, edge.attribute = NULL, transform = c("identity", "reciprocal"), dim = 2, method = c("fr", "kk"), verbose = FALSE, stage = "final" )graph.embedding( graph, edge.attribute = NULL, transform = c("identity", "reciprocal"), dim = 2, method = c("fr", "kk"), verbose = FALSE, stage = "final" )
graph |
A |
edge.attribute |
Explicit edge quantity, such as |
transform |
Use selected values directly ( |
dim |
Embedding dimension, either |
method |
Layout method, |
verbose |
Logical; print timing messages. |
stage |
Stored graph stage used for both topology and edge attributes. |
Numeric layout matrix with one row per embedded vertex.
set.seed(1) graph <- create.graph("cycle", 6) graph.embedding(graph, dim = 2, method = "fr")set.seed(1) graph <- create.graph("cycle", 6) graph.embedding(graph, dim = 2, method = "fr")
Compute exact shortest-path distances on a supplied graph, or on a graph
constructed from coordinates. These graph distances may approximate a
continuous geometric distance; construction alone does not make them exact
manifold geodesics. Supply exactly one of graph and points.
graph.geodesic.distances( graph = NULL, vertices = NULL, stage = "final", distance = c("length", "hop"), points = NULL, graph.type = NULL, k = NULL )graph.geodesic.distances( graph = NULL, vertices = NULL, stage = "final", distance = c("length", "hop"), points = NULL, graph.type = NULL, k = NULL )
graph |
A |
vertices |
Optional unique 1-based vertex indices, in output order.
|
stage |
Stored graph stage; defaults to |
distance |
|
points |
Finite numeric matrix or data frame, with one point per row
and at least one row and column. Cannot accompany |
graph.type |
Construction for coordinate input: |
k |
Required number of other neighbors for |
For repeated calculations or more construction options, build a
graph separately and supply it via graph. Coordinate construction uses
untransformed Euclidean distances. The exact symmetric-neighbor search
evaluates all pairs; MST construction uses a dense Prim search with
quadratic time and linear auxiliary storage. Selected-vertex output has
length(vertices)^2 entries; all-pairs output has n^2 entries.
A numeric square matrix in the requested vertex order; unreachable
pairs have infinite distance. Zero-length edges remain traversable. Row
names from points, or adjacency labels from graph, label the matrix
when present.
graph <- create.graph("chain", 5) graph.geodesic.distances(graph, vertices = c(1, 5)) graph.geodesic.distances(create.graph("cycle", 5), distance = "hop") X <- matrix(c(0, 0, 1, 10), ncol = 1) graph.geodesic.distances(points = X, graph.type = "mst") graph.geodesic.distances(points = X, graph.type = "sknn", k = 1)graph <- create.graph("chain", 5) graph.geodesic.distances(graph, vertices = c(1, 5)) graph.geodesic.distances(create.graph("cycle", 5), distance = "hop") X <- matrix(c(0, 0, 1, 10), ncol = 1) graph.geodesic.distances(points = X, graph.type = "mst") graph.geodesic.distances(points = X, graph.type = "sknn", k = 1)
Embed a Connected Graph Using its Positive Laplacian Spectrum
graph.spectral.embedding(spectrum, dim = 2, scale = c("none", "inverse.sqrt"))graph.spectral.embedding(spectrum, dim = 2, scale = c("none", "inverse.sqrt"))
spectrum |
A |
dim |
Positive integer number of coordinates, no greater than the
number of positive eigenpairs in |
scale |
Coordinate scaling: |
The spectrum object carries the eigenvalue ordering, zero-mode tolerance
and component information, so embedding never discards a column by position
in an arbitrary eigenvector matrix. Disconnected graphs are rejected:
embed each component separately with create.subgraph() and
graph.spectrum(). There is no implied distance between separate components.
Singleton and empty graphs have no positive-dimensional spectral embedding.
Unscaled coordinates are a spectral representation, not original physical coordinates. On a connected graph, inverse-square-root scaling using all positive modes makes squared Euclidean distances equal to effective resistance; using fewer modes gives a truncated representation. Neither choice generally reproduces shortest-path or manifold geodesic distances. Signs and bases within tied eigenvalues can vary; choose whole tied eigenspaces when comparing embedding distances across backends.
Numeric matrix with one row per vertex and columns Dim1, Dim2,
and so on. Columns use the smallest dim positive eigenvalues.
graph.spectrum(), graph.embedding()
graph <- create.graph("chain", 8) spectrum <- graph.spectrum(graph, nev = 3) graph.spectral.embedding(spectrum, dim = 2) graph.spectral.embedding(spectrum, dim = 3, scale = "inverse.sqrt")graph <- create.graph("chain", 8) spectrum <- graph.spectrum(graph, nev = 3) graph.spectral.embedding(spectrum, dim = 2) graph.spectral.embedding(spectrum, dim = 3, scale = "inverse.sqrt")
Compute the Positive Spectrum of an Unweighted Graph Laplacian
graph.spectrum( graph, nev = NULL, use.R = FALSE, return.Laplacian = FALSE, return.dense = FALSE, tol = NULL )graph.spectrum( graph, nev = NULL, use.R = FALSE, return.Laplacian = FALSE, return.dense = FALSE, tol = NULL )
graph |
A |
nev |
Number of smallest positive eigenpairs, in increasing eigenvalue
order. |
use.R |
Logical; use base R's dense symmetric eigensolver instead of the native backend. Both return the same numerical contract. |
return.Laplacian |
Logical; include the graph Laplacian in the result. |
return.dense |
Logical; return a base matrix when |
tol |
Positive absolute eigenvalue tolerance. By default, use
|
Every component contributes one zero mode, including isolated vertices.
These modes are omitted from evalues and evectors; their number is
determined from topology and checked against the computed spectrum.
The native backend uses sparse Lanczos for partial spectra, requesting the
component zero modes as well, and a dense eigensolver for the full spectrum.
The R backend computes the full dense spectrum before selection. Thus a
small explicit nev is preferable for large graphs. Dense solves require
quadratic memory; requesting all positive modes is not a sparse operation.
Eigenvector signs and bases within repeated-eigenvalue subspaces are not
unique. If nev or an embedding dimension cuts through a repeated
eigenvalue, the selected subspace and embedding distances can differ between
backends. Include the whole tied eigenspace for invariant comparisons.
A graph_spectrum list with evalues (the requested positive
eigenvalues in increasing order), evectors (one row per original vertex,
one orthonormal column per eigenvalue), nullity (the exact number of
connected components), components (component IDs in vertex order), and
the resolved tolerance. When requested, laplacian contains L.
An empty or edgeless graph has no positive modes and an n by zero
eigenvector matrix when nev = NULL or nev = 0.
graph.spectral.embedding(), graph.connected.components()
graph <- create.graph("chain", 8) spectrum <- graph.spectrum(graph, nev = 3) spectrum$evalues spectrum$nullity # one omitted zero mode graph.spectral.embedding(spectrum, dim = 2)graph <- create.graph("chain", 8) spectrum <- graph.spectrum(graph, nev = 3) spectrum$evalues spectrum$nullity # one omitted zero mode graph.spectral.embedding(spectrum, dim = 2)
Extracts one selected graph summary from two graph-like objects and computes a divergence between the resulting probability mass functions.
Currently the supported divergence is Jensen-Shannon divergence, implemented
via jensen.shannon.divergence().
graph.summary.divergence( graph1, graph2, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list(), support = NULL, return.details = TRUE )graph.summary.divergence( graph1, graph2, summary = c("degree_distribution", "edge_weight_distribution", "component_size_distribution", "neighborhood_label_distribution"), divergence = c("js"), labels = NULL, summary.args = list(), support = NULL, return.details = TRUE )
graph1 |
First |
graph2 |
Second |
summary |
Summary type to compare. |
divergence |
Divergence type. Currently only |
labels |
Optional shared vertex-label vector used for
|
summary.args |
Optional named list forwarded to
|
support |
Optional common support. If |
return.details |
Logical; if |
If return.details = TRUE, a list with fields:
summary: summary type used.
divergence: divergence type used.
value: scalar divergence value.
pmf1: aligned PMF for g1.
pmf2: aligned PMF for g2.
support: aligned support.
metadata: summary-specific metadata for both graphs.
Otherwise, returns the scalar divergence value.
path <- dgraph(list(2L, c(1L, 3L), 2L)) triangle <- dgraph(list(c(2L, 3L), c(1L, 3L), c(1L, 2L))) graph.summary.divergence( path, triangle, summary = "degree_distribution" )path <- dgraph(list(2L, c(1L, 3L), 2L)) triangle <- dgraph(list(c(2L, 3L), c(1L, 3L), c(1L, 2L))) graph.summary.divergence( path, triangle, summary = "degree_distribution" )
Weighted Graph Distance Between Graphs with Identical Vertex Sets
identical.vertex.set.weighted.graph.similarity( adj.list1, length.list1, adj.list2, length.list2, calculate.normalized.deviation = FALSE )identical.vertex.set.weighted.graph.similarity( adj.list1, length.list1, adj.list2, length.list2, calculate.normalized.deviation = FALSE )
adj.list1 |
First graph adjacency list. |
length.list1 |
First graph edge weights. |
adj.list2 |
Second graph adjacency list. |
length.list2 |
Second graph edge weights. |
calculate.normalized.deviation |
Logical; if |
Numeric distance-matrix deviation.
graph <- list(2L, c(1L, 3L), 2L) weights1 <- list(1, c(1, 1), 1) weights2 <- list(1, c(1, 2), 2) identical.vertex.set.weighted.graph.similarity( graph, weights1, graph, weights2 )graph <- list(2L, c(1L, 3L), 2L) weights1 <- list(1, c(1, 1), 1) weights2 <- list(1, c(1, 2), 2) identical.vertex.set.weighted.graph.similarity( graph, weights1, graph, weights2 )
Inspect a Path Graph
## S3 method for class 'path.graph' print(x, ...) ## S3 method for class 'path.graph' summary(object, ...)## S3 method for class 'path.graph' print(x, ...) ## S3 method for class 'path.graph' summary(object, ...)
x, object
|
A single |
... |
Unused. |
print() invisibly returns its unchanged input after printing graph
counts. summary() prints and invisibly returns a named list containing
n.vertices, n.paths, avg.path.length (number of vertices per stored
path, or NA if no paths), and avg.degree (mean adjacency-list length).
chain <- create.graph("chain", n = 5) paths <- create.path.graph(chain, h.values = 2)[[1L]] print(paths) summary(paths)chain <- create.graph("chain", n = 5) paths <- create.path.graph(chain, h.values = 2)[[1L]] print(paths) summary(paths)
Inspect a Collection of Hop-Constrained Path Graphs
## S3 method for class 'path.graph.series' summary(object, ...) ## S3 method for class 'path.graph.series' print(x, ...)## S3 method for class 'path.graph.series' summary(object, ...) ## S3 method for class 'path.graph.series' print(x, ...)
... |
Reserved for generic method arguments. |
x, object
|
A collection returned by |
summary() returns a data frame of hop limits, vertex counts,
edge counts and stored route counts. print() displays up to ten rows
and returns the original collection invisibly. No paths are recomputed.
paths <- create.path.graph(create.graph("chain", 6), h.values = c(1, 2, 4)) print(paths) summary(paths)paths <- create.path.graph(create.graph("chain", 6), h.values = c(1, 2, 4)) print(paths) summary(paths)
Inspect a Synthetic Geometry Sample
## S3 method for class 'synthetic_geometry_sample' print(x, ...) ## S3 method for class 'synthetic_geometry_sample' summary(object, ...) ## S3 method for class 'summary.synthetic_geometry_sample' print(x, ...)## S3 method for class 'synthetic_geometry_sample' print(x, ...) ## S3 method for class 'synthetic_geometry_sample' summary(object, ...) ## S3 method for class 'summary.synthetic_geometry_sample' print(x, ...)
x, object
|
A sample returned by |
... |
Reserved for generic method arguments. |
print() returns its input invisibly. summary() returns a
summary.synthetic_geometry_sample with dimensions, geometry/sampling
families, coordinate ranges, observed region counts and RNG mode. State
vectors remain available in the sample's $rng without being printed.
x <- sample.synthetic.geometry(synthetic.circle(), synthetic.sampling.uniform.interval(0, 2*pi), n = 5, seed = 17) print(x) summary(x)x <- sample.synthetic.geometry(synthetic.circle(), synthetic.sampling.uniform.interval(0, 2*pi), n = 5, seed = 17) print(x) summary(x)
Computes Pearson and Spearman correlations between estimated and true pairwise distances over the upper-triangular distance entries.
isometry.distance.correlations( D.estimated, D.true, true.tol = sqrt(.Machine$double.eps) )isometry.distance.correlations( D.estimated, D.true, true.tol = sqrt(.Machine$double.eps) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
Named numeric vector with entries pearson_cor and spearman_cor.
D <- as.matrix(dist(1:4)) isometry.distance.correlations(2 * D, D)D <- as.matrix(dist(1:4)) isometry.distance.correlations(2 * D, D)
Computes quantiles of the calibrated pairwise distortion
Values near 1 indicate approximately isometric distance preservation.
isometry.distortion.quantiles( D.estimated, D.true, probs = c(0.05, 0.5, 0.95), scale = TRUE, true.tol = sqrt(.Machine$double.eps) )isometry.distortion.quantiles( D.estimated, D.true, probs = c(0.05, 0.5, 0.95), scale = TRUE, true.tol = sqrt(.Machine$double.eps) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
probs |
Numeric vector of probabilities passed to |
scale |
Logical scalar. If |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
Named numeric vector of distortion quantiles.
D <- as.matrix(dist(1:4)) isometry.distortion.quantiles(1.1 * D, D)D <- as.matrix(dist(1:4)) isometry.distortion.quantiles(1.1 * D, D)
Computes signed and scale-regime diagnostics for comparing estimated graph
geodesic distances with reference geodesic distances. Distances are first
optionally calibrated by the least-squares scale from isometry.scale().
isometry.geodesic.diagnostics( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps), band.probs = c(1/3, 2/3) )isometry.geodesic.diagnostics( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps), band.probs = c(1/3, 2/3) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
scale |
Logical scalar. If |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
band.probs |
Numeric vector of two probabilities used to split reference distances into short, middle, and long distance bands. |
Named numeric vector with target-normalized graph-geodesic relative
RMSE, signed residual bias, shortcut fraction, relative absolute residual
quantiles, and median signed relative residuals in short/mid/long
reference-distance bands. The relative-RMSE entry retains the historical
name rel_geodesic_stress; it is not Kruskal's Stress-1.
D <- as.matrix(dist(1:4)) isometry.geodesic.diagnostics(1.1 * D, D)D <- as.matrix(dist(1:4)) isometry.geodesic.diagnostics(1.1 * D, D)
Computes quantiles of pairwise relative absolute errors
isometry.rel.abs.error( D.estimated, D.true, probs = c(0.5, 0.95), scale = TRUE, true.tol = sqrt(.Machine$double.eps) )isometry.rel.abs.error( D.estimated, D.true, probs = c(0.5, 0.95), scale = TRUE, true.tol = sqrt(.Machine$double.eps) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
probs |
Numeric vector of probabilities passed to |
scale |
Logical scalar. If |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
Named numeric vector of relative absolute error quantiles.
D <- as.matrix(dist(1:4)) isometry.rel.abs.error(1.1 * D, D)D <- as.matrix(dist(1:4)) isometry.rel.abs.error(1.1 * D, D)
Computes the relative root-mean-square distance-matrix error after optional scalar calibration:
isometry.rel.rms.error( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps) )isometry.rel.rms.error( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
scale |
Logical scalar. If |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
Numeric scalar relative RMS error.
D <- as.matrix(dist(1:4)) isometry.rel.rms.error(2 * D, D)D <- as.matrix(dist(1:4)) isometry.rel.rms.error(2 * D, D)
Computes the least-squares scalar that aligns estimated
distances to true distances:
isometry.scale(D.estimated, D.true, true.tol = sqrt(.Machine$double.eps))isometry.scale(D.estimated, D.true, true.tol = sqrt(.Machine$double.eps))
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
Numeric scalar calibration scale.
D <- as.matrix(dist(1:4)) isometry.scale(2 * D, D)D <- as.matrix(dist(1:4)) isometry.scale(2 * D, D)
Jensen-Shannon Divergence
jensen.shannon.divergence(p, q)jensen.shannon.divergence(p, q)
p |
Numeric probability vector. |
q |
Numeric probability vector. |
Jensen-Shannon divergence using log base 2.
jensen.shannon.divergence(c(0.75, 0.25), c(0.5, 0.5))jensen.shannon.divergence(c(0.75, 0.25), c(0.5, 0.5))
Join Two Adjacency-List Graphs
join.graphs(graph1, graph2, i1, i2)join.graphs(graph1, graph2, i1, i2)
graph1 |
First |
graph2 |
Second |
i1 |
Vertex in |
i2 |
Vertex in |
A dgraph with vertices i1 and i2 identified. Both inputs must
have lengths or both omit them, and must share their edge-attribute names.
first <- dgraph(list(2L, 1L)) second <- dgraph(list(2L, 1L)) join.graphs(first, second, i1 = 2, i2 = 1)first <- dgraph(list(2L, 1L)) second <- dgraph(list(2L, 1L)) join.graphs(first, second, i1 = 2, i2 = 1)
Find the Minimum Hop Limit for Path Existence
minh.limit(path.result, from, to)minh.limit(path.result, from, to)
path.result |
A |
from |
Source vertex index. |
to |
Target vertex index. |
Minimum hop limit where the path exists, or NULL.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) series <- create.path.graph(dgraph(graph, lengths), h.values = 1:2) minh.limit(series, from = 1, to = 3)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) series <- create.path.graph(dgraph(graph, lengths), h.values = 1:2) minh.limit(series, from = 1, to = 3)
Construct the Nerve Graph of a Cover
nerve.graph(covering.list, n.cores = 1)nerve.graph(covering.list, n.cores = 1)
covering.list |
List of integer vectors, one for each set in the cover. |
n.cores |
Number of parallel workers. Use |
A dgraph with no lengths and overlap cardinalities stored in the
overlap edge attribute.
cover <- list(c(1, 2, 3), c(3, 4), c(5, 6)) graph.edges(nerve.graph(cover, n.cores = 1))cover <- list(c(1, 2, 3), c(3, 4), c(5, 6)) graph.edges(nerve.graph(cover, n.cores = 1))
Plot the distribution of overlap values
overlap.distribution.plot(x, radius_idx = NULL)overlap.distribution.plot(x, radius_idx = NULL)
x |
A vertex_geodesic_stats object |
radius_idx |
Index of the radius to display. If NULL, uses the radius with the most composite geodesics. |
Invisibly returns NULL
Normalized Cumulative Distance Along a Vertex Path
path.dist(s, V)path.dist(s, V)
s |
Nonempty numeric vector of integer vertex indices in |
V |
Finite numeric vertex coordinate matrix with at least one row and one column. |
Numeric vector of length length(s). For a positive-length path,
cumulative Euclidean distances start at zero and end at one. A singleton
or zero-length path returns all zeros. Empty paths and total lengths
exceeding the finite numeric range are rejected.
path.length(), subdivide.path()
vertices <- rbind(c(0, 0), c(1, 0), c(1, 2)) path.dist(1:3, vertices) path.dist(2, vertices) # a singleton has normalized distance zerovertices <- rbind(c(0, 0), c(1, 0), c(1, 2)) path.dist(1:3, vertices) path.dist(2, vertices) # a singleton has normalized distance zero
Compute Euclidean Path Length
path.length(X)path.length(X)
X |
Finite numeric matrix whose rows are consecutive path points, with at least one row and one column. |
Total Euclidean length of the polyline. Singleton paths and paths whose points all coincide have length zero. Empty paths and total lengths exceeding the finite numeric range are rejected.
path.length(rbind(c(0, 0), c(1, 0), c(1, 2))) path.length(matrix(c(1, 2), nrow = 1)) # zeropath.length(rbind(c(0, 0), c(1, 0), c(1, 2))) path.length(matrix(c(1, 2), nrow = 1)) # zero
Plot method for build_iknn_graphs_and_selectk
## S3 method for class 'build_iknn_graphs_and_selectk' plot( x, which = c("connect", "edit", "mixing"), connect.args = list(), edit.args = list(), mixing.args = list(), par.args = list(), ... )## S3 method for class 'build_iknn_graphs_and_selectk' plot( x, which = c("connect", "edit", "mixing"), connect.args = list(), edit.args = list(), mixing.args = list(), par.args = list(), ... )
x |
Object from |
which |
Character vector selecting panels among |
connect.args, edit.args, mixing.args
|
Named lists forwarded to panel plots. |
par.args |
Named list forwarded to |
... |
Additional arguments, currently ignored. |
Invisibly returns x, unchanged, after producing the requested
panels. If which is empty, invisibly returns NULL without plotting.
set.seed(1) X <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(X, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) plot(selected, which = "connect")set.seed(1) X <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(X, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) plot(selected, which = "connect")
Plot method for cst_graph_mixing_stats
## S3 method for class 'cst_graph_mixing_stats' plot( x, which = c("null.homophily", "null.assortativity", "mixing.matrix", "conductance"), ... )## S3 method for class 'cst_graph_mixing_stats' plot( x, which = c("null.homophily", "null.assortativity", "mixing.matrix", "conductance"), ... )
x |
Object from |
which |
Character vector specifying panels to plot. |
... |
Base graphics arguments. |
Invisibly returns NULL after producing the requested diagnostic
panels.
mixing <- structure(list(mixing.matrix = matrix(c(4, 1, 1, 4), 2, dimnames = list(c("A", "B"), c("A", "B")))), class = "cst_graph_mixing_stats") plot(mixing, which = "mixing.matrix")mixing <- structure(list(mixing.matrix = matrix(c(4, 1, 1, 4), 2, dimnames = list(c("A", "B"), c("A", "B")))), class = "cst_graph_mixing_stats") plot(mixing, which = "mixing.matrix")
Draw each undirected edge once and color vertices by values or explicit
colors. Coordinates are computed by graph.embedding() only when absent.
Layout computation remains available separately in two or three dimensions.
## S3 method for class 'dgraph' plot( x, coordinates = NULL, vertex.values = NULL, vertex.colors = NULL, vertex.size = 1, edge.alpha = 0.2, color.palette = NULL, main = "", add.legend = TRUE, stage = "final", method = c("fr", "kk"), edge.attribute = NULL, transform = c("identity", "reciprocal"), projection = NULL, ... )## S3 method for class 'dgraph' plot( x, coordinates = NULL, vertex.values = NULL, vertex.colors = NULL, vertex.size = 1, edge.alpha = 0.2, color.palette = NULL, main = "", add.legend = TRUE, stage = "final", method = c("fr", "kk"), edge.attribute = NULL, transform = c("identity", "reciprocal"), projection = NULL, ... )
x |
A |
coordinates |
Optional finite numeric matrix with one row per vertex and two or three columns. Row order must match graph vertex order. |
vertex.values |
Optional finite numeric value per vertex, mapped through
|
vertex.colors |
Optional explicit color or vector of colors, one per
vertex. Cannot accompany |
vertex.size |
Nonnegative point size, one value or one per vertex. |
edge.alpha |
Edge opacity between zero and one. |
color.palette |
Color vector for numeric values; defaults to a
blue-white-red palette. Requires |
main |
Plot title. |
add.legend |
Logical; show value/color keys for numeric |
stage |
Stored graph stage, used for both layout and drawn edges. |
method |
Layout method, |
edge.attribute, transform
|
Explicit layout edge quantity and transform;
see |
projection |
For three-column coordinates, two distinct column indices
to display, for example |
... |
Named arguments to |
Invisibly returns the two-column coordinates actually drawn. These can be supplied to subsequent calls to reuse the layout. Graphics settings are restored after plotting.
graph <- create.graph("cycle", n = 6) xy <- plot(graph, vertex.values = 1:6) plot(graph, coordinates = xy, vertex.values = rep(1, 6)) xyz <- graph.embedding(graph, dim = 3) plot(graph, coordinates = xyz, projection = c(1, 3), vertex.colors = "navy")graph <- create.graph("cycle", n = 6) xy <- plot(graph, vertex.values = 1:6) plot(graph, coordinates = xy, vertex.values = rep(1, 6)) xyz <- graph.embedding(graph, dim = 3) plot(graph, coordinates = xyz, projection = c(1, 3), vertex.colors = "navy")
Creates visualizations of geodesic statistics to help understand the relationship between radius and number of geodesics.
## S3 method for class 'geodesic_stats' plot( x, plot.type = c("summary", "heatmap", "vertex", "all"), selected.vertices = NULL, max.vertices = 10, ... )## S3 method for class 'geodesic_stats' plot( x, plot.type = c("summary", "heatmap", "vertex", "all"), selected.vertices = NULL, max.vertices = 10, ... )
x |
List. Output from compute.geodesic.stats(). |
plot.type |
Character. Type of plot to generate: "summary" (default), "heatmap", "vertex", or "all". |
selected.vertices |
Integer vector. Specific vertices to highlight in "vertex" plots. If NULL, a random sample will be used. |
max.vertices |
Integer. Maximum number of vertices to show in vertex plot. |
... |
Additional arguments passed to summary |
Invisibly returns NULL.
stats <- list( radii = c(0.2, 0.4), geodesic_rays = matrix(c(2, 3, 3, 4), nrow = 2, byrow = TRUE), composite_geodesics = matrix(c(1, 1, 1, 2), nrow = 2, byrow = TRUE), grid_vertices = c(5L, 9L), summary = data.frame( radius = c(0.2, 0.4), avg_rays = c(2.5, 3.5), max_rays = c(3, 4), composite_ratio = c(0.4, 0.5), avg_overlap_median = c(0.35, 0.45) ) ) class(stats) <- c("geodesic_stats", "list") plot(stats, plot.type = "summary") plot(stats, plot.type = "vertex", selected.vertices = 5)stats <- list( radii = c(0.2, 0.4), geodesic_rays = matrix(c(2, 3, 3, 4), nrow = 2, byrow = TRUE), composite_geodesics = matrix(c(1, 1, 1, 2), nrow = 2, byrow = TRUE), grid_vertices = c(5L, 9L), summary = data.frame( radius = c(0.2, 0.4), avg_rays = c(2.5, 3.5), max_rays = c(3, 4), composite_ratio = c(0.4, 0.5), avg_overlap_median = c(0.35, 0.45) ) ) class(stats) <- c("geodesic_stats", "list") plot(stats, plot.type = "summary") plot(stats, plot.type = "vertex", selected.vertices = 5)
Plot Method for IkNN Stability Metrics
## S3 method for class 'iknn_stability_metrics' plot(x, ...)## S3 method for class 'iknn_stability_metrics' plot(x, ...)
x |
An object returned by |
... |
Passed to |
Invisibly returns TRUE after producing the stability diagnostic
plot.
set.seed(1) X <- matrix(rnorm(60), ncol = 2) graphs <- create.iknn.graphs(X, k.values = seq.int(2, 4), compute.full = TRUE, verbose = FALSE) stability <- compute.stability.metrics(graphs) plot(stability, with.pwlm = FALSE)set.seed(1) X <- matrix(rnorm(60), ncol = 2) graphs <- create.iknn.graphs(X, k.values = seq.int(2, 4), compute.full = TRUE, verbose = FALSE) stability <- compute.stability.metrics(graphs) plot(stability, with.pwlm = FALSE)
Plot Diagnostics for Intersection k-NN Graph Analysis
## S3 method for class 'IkNNgraphs' plot( x, type = "diag", diags = c("edist", "edge", "deg"), with.pwlm = TRUE, with.lmin = FALSE, breakpoint.col = "blue", lmin.col = "gray", mar = c(2.5, 2.5, 0.5, 0.5), mgp = c(2.5, 0.5, 0), tcl = -0.3, xline = 2.4, yline = 3.15, ... )## S3 method for class 'IkNNgraphs' plot( x, type = "diag", diags = c("edist", "edge", "deg"), with.pwlm = TRUE, with.lmin = FALSE, breakpoint.col = "blue", lmin.col = "gray", mar = c(2.5, 2.5, 0.5, 0.5), mgp = c(2.5, 0.5, 0), tcl = -0.3, xline = 2.4, yline = 3.15, ... )
x |
A list with |
type |
Character string. Only |
diags |
Diagnostic panels. The supported combination is
|
with.pwlm |
Logical. If |
with.lmin |
Logical. If |
breakpoint.col |
Color for breakpoint vertical lines. |
lmin.col |
Color for local-minima vertical lines. |
mar, mgp, tcl, xline, yline
|
Base graphics controls. |
... |
Additional arguments passed to plot. |
Invisibly returns TRUE.
diagnostics <- structure(list(k.values = 2:4, edit.distances = c(0.3, 0.2), n.edges.in.pruned.graph = c(6, 8, 10), js.div = c(0.1, 0.05)), class = "IkNNgraphs") plot(diagnostics, with.pwlm = FALSE)diagnostics <- structure(list(k.values = 2:4, edit.distances = c(0.3, 0.2), n.edges.in.pruned.graph = c(6, 8, 10), js.div = c(0.1, 0.05)), class = "IkNNgraphs") plot(diagnostics, with.pwlm = FALSE)
Plot method for vertex_geodesic_stats objects
## S3 method for class 'vertex_geodesic_stats' plot(x, ...)## S3 method for class 'vertex_geodesic_stats' plot(x, ...)
x |
A vertex_geodesic_stats object |
... |
Additional arguments passed to plot |
Invisibly returns NULL
x <- data.frame( radius = c(0.2, 0.4, 0.6), rays = c(3, 5, 6), composite_geodesics = c(1, 2, 3), overlap_min = c(0.10, 0.15, 0.20), overlap_p05 = c(0.15, 0.20, 0.25), overlap_p25 = c(0.20, 0.25, 0.30), overlap_median = c(0.30, 0.40, 0.50), overlap_p75 = c(0.40, 0.50, 0.60), overlap_p95 = c(0.55, 0.65, 0.75), overlap_max = c(0.60, 0.70, 0.80), potential_pairs = c(3, 10, 15), composite_ratio = c(1/3, 0.2, 0.2), overlap_ratio = c(0.30, 0.40, 0.50) ) class(x) <- c("vertex_geodesic_stats", "data.frame") attr(x, "vertex") <- 7L plot(x)x <- data.frame( radius = c(0.2, 0.4, 0.6), rays = c(3, 5, 6), composite_geodesics = c(1, 2, 3), overlap_min = c(0.10, 0.15, 0.20), overlap_p05 = c(0.15, 0.20, 0.25), overlap_p25 = c(0.20, 0.25, 0.30), overlap_median = c(0.30, 0.40, 0.50), overlap_p75 = c(0.40, 0.50, 0.60), overlap_p95 = c(0.55, 0.65, 0.75), overlap_max = c(0.60, 0.70, 0.80), potential_pairs = c(3, 10, 15), composite_ratio = c(1/3, 0.2, 0.2), overlap_ratio = c(0.30, 0.40, 0.50) ) class(x) <- c("vertex_geodesic_stats", "data.frame") attr(x, "vertex") <- 7L plot(x)
Print method for build_iknn_graphs_and_selectk
## S3 method for class 'build_iknn_graphs_and_selectk' print(x, ...)## S3 method for class 'build_iknn_graphs_and_selectk' print(x, ...)
x |
Object from |
... |
Unused. |
Invisibly returns x, unchanged, after printing its selected
neighborhood sizes and trimming status.
set.seed(1) X <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(X, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) print(selected)set.seed(1) X <- matrix(rnorm(60), ncol = 2) selected <- build.iknn.graphs.and.selectk(X, k.values = seq.int(2, 4), method = "edit", verbose = FALSE) print(selected)
Print an Undirected Graph
## S3 method for class 'dgraph' print(x, ...)## S3 method for class 'dgraph' print(x, ...)
x |
A |
... |
Unused. |
The unchanged graph, invisibly.
print(create.graph("empty", 3))print(create.graph("empty", 3))
Prints a brief overview of the geodesic statistics.
## S3 method for class 'geodesic_stats' print(x, ...)## S3 method for class 'geodesic_stats' print(x, ...)
x |
A geodesic_stats object from compute.geodesic.stats(). |
... |
Additional arguments passed to print. |
The object invisibly.
graph <- create.graph("circle", n = 8, sampling = "uniform") stats <- compute.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), min.radius = 0.3, max.radius = 0.5, n.steps = 2, n.packing.vertices = 4) print(stats)graph <- create.graph("circle", n = 8, sampling = "uniform") stats <- compute.geodesic.stats(graph.adjacency(graph), graph.lengths(graph), min.radius = 0.3, max.radius = 0.5, n.steps = 2, n.packing.vertices = 4) print(stats)
Print Graph Constructor Results
## S3 method for class 'radius_graph' print(x, ...) ## S3 method for class 'cknn_graph' print(x, ...) ## S3 method for class 'rknn_graphs' print(x, ...) ## S3 method for class 'adaptive_radius_graph' print(x, ...) ## S3 method for class 'sknn_graphs' print(x, ...) ## S3 method for class 'sknn_graph' print(x, ...)## S3 method for class 'radius_graph' print(x, ...) ## S3 method for class 'cknn_graph' print(x, ...) ## S3 method for class 'rknn_graphs' print(x, ...) ## S3 method for class 'adaptive_radius_graph' print(x, ...) ## S3 method for class 'sknn_graphs' print(x, ...) ## S3 method for class 'sknn_graph' print(x, ...)
x |
A graph or graph-sequence object returned by the corresponding constructor. |
... |
Unused. |
The input object x, invisibly and unchanged. Prints vertex and
edge counts, construction parameters, and connectivity information when
present; for a sequence, prints the graph count and neighborhood sizes.
X <- cbind(seq_len(8), sin(seq_len(8))) print(create.rknn.graph(X, type = "fixed", radius = 2)) print(create.cknn.graph(X, k.scale = 2)) print(create.rknn.graph(X, type = "adaptive.radius", k.scale = 2)) print(create.rknn.graphs(X, k.values = seq.int(2, 3))) print(create.sknn.graph(X, k = 2))X <- cbind(seq_len(8), sin(seq_len(8))) print(create.rknn.graph(X, type = "fixed", radius = 2)) print(create.cknn.graph(X, k.scale = 2)) print(create.rknn.graph(X, type = "adaptive.radius", k.scale = 2)) print(create.rknn.graphs(X, k.values = seq.int(2, 3))) print(create.sknn.graph(X, k = 2))
Prints a summary of the outlier detection results from remove.knn.outliers.
## S3 method for class 'knn.outliers' print(x, ...)## S3 method for class 'knn.outliers' print(x, ...)
x |
An object of class "knn.outliers" as returned by |
... |
Additional arguments passed to |
Invisibly returns the input object.
knn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" knn.resknn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" knn.res
Print Method for Maximal Packing Results
## S3 method for class 'maximal_packing' print(x, ...)## S3 method for class 'maximal_packing' print(x, ...)
x |
An object of class "maximal_packing" |
... |
Additional arguments (currently ignored) |
Invisible copy of x
x <- list( graph = create.graph("chain", 4), graph_diameter = 3, max_packing_radius = 1.5, grid_vertices = c(1L, 4L) ) class(x) <- "maximal_packing" xx <- list( graph = create.graph("chain", 4), graph_diameter = 3, max_packing_radius = 1.5, grid_vertices = c(1L, 4L) ) class(x) <- "maximal_packing" x
Prints a concise summary of a mutual k-nearest neighbor graph object.
## S3 method for class 'mknn_graph' print(x, ...)## S3 method for class 'mknn_graph' print(x, ...)
x |
An object of class "mknn_graph". |
... |
Additional arguments (currently unused). |
Invisibly returns the input object.
graph <- create.mknn.graph(matrix(c(0, 1, 3, 6), ncol = 1), k = 2) print(graph)graph <- create.mknn.graph(matrix(c(0, 1, 3, 6), ncol = 1), k = 2) print(graph)
Prints a concise summary of a collection of mutual k-nearest neighbor graphs.
## S3 method for class 'mknn_graphs' print(x, ...)## S3 method for class 'mknn_graphs' print(x, ...)
x |
An object of class "mknn_graphs". |
... |
Additional arguments (currently unused). |
Invisibly returns the input object.
graphs <- create.mknn.graphs(matrix(c(0, 1, 3, 6, 9), ncol = 1), k.values = 1:3, verbose = FALSE) print(graphs)graphs <- create.mknn.graphs(matrix(c(0, 1, 3, 6, 9), ncol = 1), k.values = 1:3, verbose = FALSE) print(graphs)
Displays a concise summary of an MST completion graph object, including basic graph statistics and parameter information.
## S3 method for class 'mst_completion_graph' print(x, ...)## S3 method for class 'mst_completion_graph' print(x, ...)
x |
An object of class |
... |
Additional arguments (currently ignored). |
This method provides a human-readable overview of the graph structure without
displaying the full adjacency lists. For detailed inspection of graph
components, use graph accessors with the desired stage.
summary method.
Invisibly returns the input object x.
summary.mst_completion_graph for more detailed summaries,
create.cmst.graph for creating MST completion graphs
X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)
Print Method for Packing Validation Results
## S3 method for class 'packing_validation' print(x, ...)## S3 method for class 'packing_validation' print(x, ...)
x |
An object of class "packing_validation" |
... |
Additional arguments (currently ignored) |
Invisible copy of x
x <- list( valid = TRUE, is.maximal = TRUE, min.packing.distance = 2, max.coverage.distance = 1, violations = NULL, potential.additions = NULL ) class(x) <- "packing_validation" xx <- list( valid = TRUE, is.maximal = TRUE, min.packing.distance = 2, max.coverage.distance = 1, violations = NULL, potential.additions = NULL ) class(x) <- "packing_validation" x
Print a Path-Length-Metric Graph
## S3 method for class 'path.graph.plm' print(x, ...)## S3 method for class 'path.graph.plm' print(x, ...)
x |
A |
... |
Unused. |
Invisibly returns x unchanged after printing its vertex, edge and
stored-path counts and maximum path length.
graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) create.plm.graph(graph, lengths, h = 3)graph <- list(2L, c(1L, 3L), 2L) lengths <- list(1, c(1, 2), 2) create.plm.graph(graph, lengths, h = 3)
Prints the summary of outlier detection results.
## S3 method for class 'summary.knn.outliers' print(x, ...)## S3 method for class 'summary.knn.outliers' print(x, ...)
x |
An object of class "summary.knn.outliers". |
... |
Additional arguments passed to |
Invisibly returns the input object.
knn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" summary(knn.res)knn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" summary(knn.res)
Formats and displays the summary information for an MST completion graph in a readable format.
## S3 method for class 'summary.mst_completion_graph' print(x, digits = 3L, ...)## S3 method for class 'summary.mst_completion_graph' print(x, digits = 3L, ...)
x |
An object of class |
digits |
Integer; number of significant digits for numeric output. Default is 3. |
... |
Additional arguments (currently ignored). |
Invisibly returns the input summary object.
X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)
Evaluate gradients of all quadforms
quadform.gradient(geometry, latent)quadform.gradient(geometry, latent)
geometry |
A |
latent |
Finite latent coordinates in rows. |
For one form, an n by d matrix. For multiple forms, an
n by r by d array. With no forms, an n by zero by d array.
geometry <- synthetic.quadform(1L, 2L, forms = list(matrix(1))) quadform.gradient(geometry, matrix(c(-1, 0, 1), ncol = 1))geometry <- synthetic.quadform(1L, 2L, forms = list(matrix(1))) quadform.gradient(geometry, matrix(c(-1, 0, 1), ncol = 1))
Evaluate the induced metric of a quadform geometry
quadform.metric(geometry, latent)quadform.metric(geometry, latent)
geometry |
A |
latent |
Finite latent coordinates in rows. |
For one row, a d by d matrix; otherwise an
n by d by d array.
geometry <- synthetic.quadform(1L, 2L, forms = list(matrix(1))) quadform.metric(geometry, matrix(c(0, 1), ncol = 1))geometry <- synthetic.quadform(1L, 2L, forms = list(matrix(1))) quadform.metric(geometry, matrix(c(0, 1), ncol = 1))
Read the existing dggraphui benchmark manifest and asset tables without launching Shiny or changing any files. Asset paths relative to the run directory are resolved against that directory; absolute paths are retained.
read.graph.benchmark(project)read.graph.benchmark(project)
project |
Benchmark directory, quadform benchmark manifest file, or registered project name. |
A list containing the manifest, dataset and graph indexes, saved layout index, metrics, diagnostics, and table summaries. This validates required index files; it does not guarantee that every referenced asset exists or that the scientific results are correct. Assets are loaded on demand by the explorer, which reports missing files.
explore.graphs(), register.graph.project()
## Not run: run <- read.graph.benchmark("path/to/benchmark/run") run$summary head(run$metrics) ## End(Not run)## Not run: run <- read.graph.benchmark("path/to/benchmark/run") run$summary head(run$metrics) ## End(Not run)
Register an existing benchmark directory for the explorer's project picker. Only its name and location are saved. Scientific assets stay in place.
register.graph.project(project, name, overwrite = FALSE)register.graph.project(project, name, overwrite = FALSE)
project |
Benchmark directory or quadform benchmark manifest file. |
name |
A nonempty, unique display name; it can also be passed as
|
overwrite |
Allow an existing name to point to a different directory. |
The updated project catalog, invisibly, with name and path
columns. Set options(dgraphs.projects_dir = ...) to change its location.
explore.graphs(), read.graph.benchmark()
## Not run: register.graph.project("path/to/benchmark/run", name = "My graph study") explore.graphs(project = "My graph study") ## End(Not run)## Not run: register.graph.project("path/to/benchmark/run", name = "My graph study") explore.graphs(project = "My graph study") ## End(Not run)
Identifies and removes outliers from a multivariate state space based on k-nearest neighbor distances. This function implements several strategies for outlier detection, all based on the principle that outliers tend to be isolated from the main data clusters and thus have larger distances to their nearest neighbors.
remove.knn.outliers( S, y = NULL, p = 0.98, dist.factor = 100, k = 30, method = "diff.dist.factor" )remove.knn.outliers( S, y = NULL, p = 0.98, dist.factor = 100, k = 30, method = "diff.dist.factor" )
S |
A numeric matrix or data frame representing the state space, where each row is an observation
and each column is a dimension or feature. Must contain at least |
y |
An optional numeric vector containing values of a variable defined over the state space.
If provided, must have length equal to |
p |
A numeric value between 0 and 1 (exclusive) indicating the percentile threshold for outlier removal. The default value of 0.98 removes points whose distance to the nearest neighbor exceeds the 98th percentile of all nearest neighbor distances. |
dist.factor |
A positive numeric value used as a threshold factor in certain outlier detection methods. In "diff.dist.factor", points with relative jumps greater than this factor are considered outliers. Default is 100. |
k |
A positive integer specifying the number of nearest neighbors to compute for each point.
Must be less than the number of observations in |
method |
A character string specifying the outlier detection method to use when k > 1. Must be one of "dist.factor", "diff.dist.factor" (default), or "default" for the unnamed method. |
The function determines outliers by analyzing the distances between points and their k nearest neighbors. Several detection methods are available:
Points are flagged as outliers if their distance to the nearest neighbor exceeds the p-th percentile threshold of all nearest neighbor distances.
Points are considered outliers if the ratio of the k-th nearest neighbor
distance to the 1st nearest neighbor distance exceeds dist.factor.
For each point, finds the maximum jump in distance between
consecutive neighbors, normalizes by the median jump across all points, and flags points as
outliers if their relative jump exceeds dist.factor. This method is particularly robust
as it adapts to the overall distribution of distances.
Iteratively checks if the first nearest neighbor distance exceeds the threshold or if any consecutive difference between neighbor distances exceeds the threshold.
A list of class "knn.outliers" containing the following components:
The filtered state space matrix with outliers removed.
The filtered dependent variable (if y was provided), otherwise NULL.
A matrix of dimensions nrow(S) x k containing distances to the k
nearest neighbors for each point.
The distance threshold used for outlier detection.
A logical vector indicating which points were kept (TRUE) and which were
identified as outliers (FALSE).
The number of outliers detected.
The outlier detection method used.
get.knn for the k-nearest neighbor calculation,
quantile for percentile calculations
# Create a sample dataset with outliers set.seed(123) n_normal <- 120 n_outliers <- 6 # Generate normal data normal_data <- matrix(rnorm(n_normal * 2), ncol = 2) # Generate outliers far from the main cluster outliers <- cbind(rnorm(n_outliers, mean = 10, sd = 0.5), rnorm(n_outliers, mean = 10, sd = 0.5)) # Combine data S <- rbind(normal_data, outliers) y <- c(rnorm(n_normal), rnorm(n_outliers, mean = 5)) # Remove outliers using the default method result <- remove.knn.outliers(S, y, k = 10) # Print summary cat("Number of outliers detected:", result$n.outliers, "\n") cat("Percentage of data retained:", round(100 * nrow(result$S.q) / nrow(S), 2), "%\n") # Use a different method with more conservative threshold result2 <- remove.knn.outliers(S, y, p = 0.95, method = "dist.factor", dist.factor = 5, k = 10) # Plot the original and filtered state space oldpar <- par(mfrow = c(1, 2)) plot(S, col = "gray", main = "Original State Space", xlab = "Dimension 1", ylab = "Dimension 2") points(S[!result$idx, ], col = "red", pch = 16, cex = 1.2) plot(result$S.q, col = "blue", pch = 16, main = "Filtered State Space", xlab = "Dimension 1", ylab = "Dimension 2") legend("topright", legend = c("Retained", "Removed"), col = c("blue", "red"), pch = 16) par(oldpar)# Create a sample dataset with outliers set.seed(123) n_normal <- 120 n_outliers <- 6 # Generate normal data normal_data <- matrix(rnorm(n_normal * 2), ncol = 2) # Generate outliers far from the main cluster outliers <- cbind(rnorm(n_outliers, mean = 10, sd = 0.5), rnorm(n_outliers, mean = 10, sd = 0.5)) # Combine data S <- rbind(normal_data, outliers) y <- c(rnorm(n_normal), rnorm(n_outliers, mean = 5)) # Remove outliers using the default method result <- remove.knn.outliers(S, y, k = 10) # Print summary cat("Number of outliers detected:", result$n.outliers, "\n") cat("Percentage of data retained:", round(100 * nrow(result$S.q) / nrow(S), 2), "%\n") # Use a different method with more conservative threshold result2 <- remove.knn.outliers(S, y, p = 0.95, method = "dist.factor", dist.factor = 5, k = 10) # Plot the original and filtered state space oldpar <- par(mfrow = c(1, 2)) plot(S, col = "gray", main = "Original State Space", xlab = "Dimension 1", ylab = "Dimension 2") points(S[!result$idx, ], col = "red", pch = 16, cex = 1.2) plot(result$S.q, col = "blue", pch = 16, main = "Filtered State Space", xlab = "Dimension 1", ylab = "Dimension 2") legend("topright", legend = c("Retained", "Removed"), col = c("blue", "red"), pch = 16) par(oldpar)
Remove Self-Loops from an Adjacency List
rm.self.loops(adj.list)rm.self.loops(adj.list)
adj.list |
Adjacency list. |
The adjacency list with entries equal to their vertex index removed.
rm.self.loops(list(c(1L, 2L), c(1L, 2L)))rm.self.loops(list(c(1L, 2L), c(1L, 2L)))
Coordinates and sampling algorithms retain the existing version-1 draw order. With a seed or explicit state list, the caller's RNG kinds and seed presence/value are restored on success and errors. The opt-in current-stream mode instead advances the caller's stream. No statistical response or dataset identity is created.
sample.synthetic.geometry( geometry, sampling, n = NULL, seed = NULL, rng.plan = NULL )sample.synthetic.geometry( geometry, sampling, n = NULL, seed = NULL, rng.plan = NULL )
geometry |
A supported geometry component. |
sampling |
A supported sampling component. Legacy G4 is excluded. |
n |
Positive sample size, or |
seed |
Nonnegative integer seed for standalone L'Ecuyer-CMRG sampling.
Supply exactly one of |
rng.plan |
Optional list with exactly |
A synthetic_geometry_sample list containing predictors, latent,
latent.mask, region, frame.matrix, the specifications, dimensions,
intrinsic.dim.by.region and codimension.by.region for simplex strata,
declared.regions, observed.regions, n, and sample (the original sampler payload). rng contains the
effective plan, states after each draw, and final.state for explicit
continuation by a caller. In current-stream mode the plan is "current";
returned state vectors are observations, not complete replay tokens for
generators with hidden state. A deterministic draw can leave these vectors
NULL if no seed exists. The result has no truth or response fields.
x <- sample.synthetic.geometry(synthetic.circle(), synthetic.sampling.uniform.interval(0, 2 * pi), n = 8, seed = 7) dim(x$predictors)x <- sample.synthetic.geometry(synthetic.circle(), synthetic.sampling.uniform.interval(0, 2 * pi), n = 8, seed = 7) dim(x$predictors)
Subdivide a Path into Arc-Length Spaced Points
subdivide.path(path, n.subdivision.pts)subdivide.path(path, n.subdivision.pts)
path |
Finite numeric matrix of consecutive path points, with at least one row and one column. Repeated consecutive points are allowed. |
n.subdivision.pts |
Integer number of output points, at least two. |
Points are interpolated at equally spaced cumulative Euclidean distances along the input polyline. Zero-length segments are skipped. Equal spacing along the polyline does not imply equal straight-line distances between output points that straddle a corner, and an interior vertex need not appear in the output. Distances are evaluated in floating-point arithmetic; paths whose total length exceeds the finite numeric range are rejected.
Numeric matrix with n.subdivision.pts rows and ncol(path) columns,
preserving coordinate column names. The first and last rows are the path
endpoints. A singleton or zero-length path repeats its location in every
output row. Empty paths are rejected.
path <- rbind(c(0, 0), c(1, 0), c(1, 2)) subdivide.path(path, n.subdivision.pts = 5) # Arc distances 0, 0.75, 1.5, 2.25, 3 give: # (0, 0), (0.75, 0), (1, 0.5), (1, 1.25), (1, 2). subdivide.path(matrix(c(1, 2), nrow = 1), n.subdivision.pts = 3)path <- rbind(c(0, 0), c(1, 0), c(1, 2)) subdivide.path(path, n.subdivision.pts = 5) # Arc distances 0, 0.75, 1.5, 2.25, 3 give: # (0, 0), (0.75, 0), (1, 0.5), (1, 1.25), (1, 2). subdivide.path(matrix(c(1, 2), nrow = 1), n.subdivision.pts = 3)
Computes the standard benchmark summary used to compare graph geodesic distances with reference geodesic distances: optimal scalar calibration, relative RMS error, relative absolute error quantiles, multiplicative distortion quantiles, and distance correlations.
summarize.isometry.deviation( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps) )summarize.isometry.deviation( D.estimated, D.true, scale = TRUE, true.tol = sqrt(.Machine$double.eps) )
D.estimated |
Estimated distance matrix or |
D.true |
Ground-truth distance matrix or |
scale |
Logical scalar. If |
true.tol |
Non-negative tolerance. Pairs with true distance less than or equal to this value are excluded from relative metrics. |
A one-row data frame.
D <- as.matrix(dist(1:4)) summarize.isometry.deviation(1.1 * D, D)D <- as.matrix(dist(1:4)) summarize.isometry.deviation(1.1 * D, D)
Provides a summary table of geodesic statistics with percentages and counts for different metric types.
## S3 method for class 'geodesic_stats' summary(object, type = c("rays", "composite", "overlap"), ...)## S3 method for class 'geodesic_stats' summary(object, type = c("rays", "composite", "overlap"), ...)
object |
A geodesic_stats object from compute.geodesic.stats(). |
type |
Character. Type of summary to generate: "rays" (default), "composite", or "overlap". |
... |
Additional arguments passed to summary. |
A matrix with row for each radius and columns for each unique count value. Each cell contains a string with "percent (count)" format.
stats <- list( radii = c(0.2, 0.4), geodesic_rays = matrix(c(2, 3, 3, 4), nrow = 2, byrow = TRUE), composite_geodesics = matrix(c(1, 1, 1, 2), nrow = 2, byrow = TRUE), path_overlap = list( min = matrix(c(0.1, 0.2, 0.2, 0.3), nrow = 2, byrow = TRUE), p05 = matrix(c(0.1, 0.2, 0.2, 0.3), nrow = 2, byrow = TRUE), p25 = matrix(c(0.2, 0.3, 0.3, 0.4), nrow = 2, byrow = TRUE), median = matrix(c(0.3, 0.4, 0.4, 0.5), nrow = 2, byrow = TRUE), p75 = matrix(c(0.4, 0.5, 0.5, 0.6), nrow = 2, byrow = TRUE), p95 = matrix(c(0.5, 0.6, 0.6, 0.7), nrow = 2, byrow = TRUE), max = matrix(c(0.6, 0.7, 0.7, 0.8), nrow = 2, byrow = TRUE) ) ) class(stats) <- c("geodesic_stats", "list") summary(stats) summary(stats, type = "composite") summary(stats, type = "overlap")stats <- list( radii = c(0.2, 0.4), geodesic_rays = matrix(c(2, 3, 3, 4), nrow = 2, byrow = TRUE), composite_geodesics = matrix(c(1, 1, 1, 2), nrow = 2, byrow = TRUE), path_overlap = list( min = matrix(c(0.1, 0.2, 0.2, 0.3), nrow = 2, byrow = TRUE), p05 = matrix(c(0.1, 0.2, 0.2, 0.3), nrow = 2, byrow = TRUE), p25 = matrix(c(0.2, 0.3, 0.3, 0.4), nrow = 2, byrow = TRUE), median = matrix(c(0.3, 0.4, 0.4, 0.5), nrow = 2, byrow = TRUE), p75 = matrix(c(0.4, 0.5, 0.5, 0.6), nrow = 2, byrow = TRUE), p95 = matrix(c(0.5, 0.6, 0.6, 0.7), nrow = 2, byrow = TRUE), max = matrix(c(0.6, 0.7, 0.7, 0.8), nrow = 2, byrow = TRUE) ) ) class(stats) <- c("geodesic_stats", "list") summary(stats) summary(stats, type = "composite") summary(stats, type = "overlap")
Prints a summary of an IkNN graph object, including the number of vertices, edges, and pruning statistics.
## S3 method for class 'IkNN' summary(object, ...)## S3 method for class 'IkNN' summary(object, ...)
object |
An object of class "IkNN", typically output from create.single.iknn.graph() |
... |
Additional arguments passed to summary(). |
Invisibly returns NULL while printing summary information to the console
graph <- create.single.iknn.graph(matrix(c(0, 1, 3, 6), ncol = 1), k = 1, verbose = FALSE) summary(graph)graph <- create.single.iknn.graph(matrix(c(0, 1, 3, 6), ncol = 1), k = 1, verbose = FALSE) summary(graph)
Provides a detailed summary of an iknn_graphs object created by the create.iknn.graphs() function. The summary includes statistics for each intersection kNN graph in the sequence, displaying information about the connectivity and structure of the graphs for different k values.
## S3 method for class 'iknn_graphs' summary(object, use.isize.pruned = FALSE, ...)## S3 method for class 'iknn_graphs' summary(object, use.isize.pruned = FALSE, ...)
object |
An object of class 'iknn_graphs', typically the output of create.iknn.graphs(). |
use.isize.pruned |
Logical. If TRUE, computes and displays statistics for the intersection-size pruned graphs (isize_pruned_graphs). If FALSE (default), computes statistics for the geometrically pruned graphs (geom_pruned_graphs). |
... |
Additional arguments passed to or from other methods (not currently used). |
The summary function extracts and presents key statistics about the structure of each intersection kNN graph in the iknn_graphs object. All graphs share the same number of vertices (equal to the number of rows in the input data matrix), but they differ in the number of edges due to varying k values and the pruning methods applied during graph creation.
The function displays general information about the graph sequence, including the number of vertices, the range of k values, and the pruning parameters used. It then presents a tabular summary of statistics for each individual graph, showing how the graph structure changes as k increases.
For each intersection kNN graph, the following metrics are calculated:
Number of edges: Total number of connections in the graph
Mean degree: Average number of connections per vertex
Min/Max degree: Range of vertex connectivity
Density: Proportion of potential connections that are actually present
Sparsity: 1 - density, measuring the proportion of missing connections
Invisibly returns a data frame containing statistics for each graph. The data frame has the following columns:
idx |
The index of the given k value |
k |
The k value for the intersection kNN graph |
n_ccomp |
Number of connected components of the graph |
edges |
Number of edges in the graph |
mean_degree |
Average number of connections per vertex |
min_degree |
Minimum vertex degree (least connected vertex) |
max_degree |
Maximum vertex degree (most connected vertex) |
sparsity |
Graph sparsity, calculated as 1 - density. It measures how many (proportion) potential connections are missing. |
create.iknn.graphs for creating intersection kNN graphs.
# Create sample data set.seed(123) x <- matrix(rnorm(1000), ncol = 5) # Generate intersection kNN graphs iknn.res <- create.iknn.graphs(x, k.values = seq.int(3, 10), with.isize.pruning = TRUE) # Summarize the geometrically pruned graphs summary(iknn.res) # Summarize the intersection-size pruned graphs summary(iknn.res, use.isize.pruned = TRUE)# Create sample data set.seed(123) x <- matrix(rnorm(1000), ncol = 5) # Generate intersection kNN graphs iknn.res <- create.iknn.graphs(x, k.values = seq.int(3, 10), with.isize.pruning = TRUE) # Summarize the geometrically pruned graphs summary(iknn.res) # Summarize the intersection-size pruned graphs summary(iknn.res, use.isize.pruned = TRUE)
Summarize Iterated Intersection k-NN Graphs
## S3 method for class 'iterated_iknn_graphs' summary(object, ...)## S3 method for class 'iterated_iknn_graphs' summary(object, ...)
object |
An object from |
... |
Unused. |
A data frame with one row per iteration and neighborhood size,
reporting vertex, edge and connected-component counts and mean, minimum
and maximum degree. This is the object's stored summary component.
set.seed(1) X <- matrix(rnorm(30), ncol = 2) out <- create.iterated.iknn.graphs(X, k.values = seq.int(2, 3), n.iterations = 1, verbose = FALSE) summary(out)set.seed(1) X <- matrix(rnorm(30), ncol = 2) out <- create.iterated.iknn.graphs(X, k.values = seq.int(2, 3), n.iterations = 1, verbose = FALSE) summary(out)
Provides a detailed summary of the outlier detection results from remove.knn.outliers.
## S3 method for class 'knn.outliers' summary(object, ...)## S3 method for class 'knn.outliers' summary(object, ...)
object |
An object of class "knn.outliers" as returned by |
... |
Additional arguments (currently unused). |
A list of class "summary.knn.outliers" containing summary statistics.
knn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" summary(knn.res)knn.res <- list( S.q = matrix(c(0, 0, 1, 1, 2, 2), ncol = 2, byrow = TRUE), y.q = c(1.0, 1.5, 2.0), nn.d = matrix(c(0.2, 0.4, 0.3, 0.5, 1.4, 1.8, 0.25, 0.45), ncol = 2, byrow = TRUE), d.thld = 1, idx = c(TRUE, TRUE, FALSE, TRUE), n.outliers = 1L, method = "qf" ) class(knn.res) <- "knn.outliers" summary(knn.res)
Summarize Local Extrema
## S3 method for class 'local_extrema' summary(object, ...) ## S3 method for class 'summary.local_extrema' print(x, ...)## S3 method for class 'local_extrema' summary(object, ...) ## S3 method for class 'summary.local_extrema' print(x, ...)
object |
A |
... |
Unused. |
x |
A |
summary() returns a list of class summary.local_extrema with
n_extrema, extrema_type, summaries of function values, neighborhood
sizes and radii, and the data frame extrema_details (labels, vertex
indices, values, radii and neighborhood sizes). With no extrema, numerical
summaries are NA and the data frame is empty; the type is NA for legacy
empty objects without detection-type metadata. print() prints this
summary and invisibly returns x unchanged.
chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) summary(extrema) print(summary(extrema))chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) summary(extrema) print(summary(extrema))
Provides a comprehensive summary of mutual k-nearest neighbor graphs created
by create.mknn.graphs, including structural statistics and connectivity
information for each k value.
## S3 method for class 'mknn_graphs' summary(object, ...)## S3 method for class 'mknn_graphs' summary(object, ...)
object |
An object of class "mknn_graphs", typically output from
|
... |
Additional arguments (currently unused). |
The summary provides insights into how graph structure changes with k:
Connected Components: Indicates graph fragmentation. A value of 1 means the graph is fully connected.
Degree Statistics: Shows the distribution of vertex connectivity. Large differences between min and max degree may indicate hub vertices.
Density/Sparsity: Measures how many of the possible edges are present. MkNN graphs are typically very sparse.
For pruned graphs, the statistics reflect the structure after geometric pruning has been applied.
Invisibly returns a data frame containing graph statistics with columns:
Index of the k value (1 to number of graphs)
The k value used for the graph
Number of connected components
Number of edges in the graph
Average vertex degree
Minimum vertex degree
Maximum vertex degree
Graph density (proportion of possible edges present)
Graph sparsity (1 - density)
graphs <- create.mknn.graphs(matrix(c(0, 1, 3, 6, 9), ncol = 1), k.values = 1:3, compute.full = TRUE, verbose = FALSE) summary(graphs)graphs <- create.mknn.graphs(matrix(c(0, 1, 3, 6, 9), ncol = 1), k.values = 1:3, compute.full = TRUE, verbose = FALSE) summary(graphs)
Computes and returns a comprehensive summary of an MST completion graph, including graph statistics, edge weight distributions, and PCA information if applicable.
## S3 method for class 'mst_completion_graph' summary(object, ...)## S3 method for class 'mst_completion_graph' summary(object, ...)
object |
An object of class |
... |
Additional arguments (currently ignored). |
An object of class summary.mst_completion_graph containing:
n_verticesNumber of vertices in the graph
n_mst_edgesNumber of edges in the minimal spanning tree
n_cmst_edgesNumber of edges in the completed graph
q_thldQuantile threshold used for completion
edge_weight_summaryFive-number summary of MST edge weights
completion_thresholdThe actual distance threshold used
pca_appliedLogical indicating if PCA was applied
pca_infoPCA details (if applicable)
print.summary.mst_completion_graph for printing summaries,
create.cmst.graph for creating graphs
X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)X <- rbind(c(0, 0), c(1, 0), c(0, 1), c(2, 2)) graph <- create.cmst.graph(X, verbose = FALSE) print(graph) summary(graph)
Provides a compact table of graph characteristics for an
"rknn_graphs" object created by create.rknn.graphs(). The table reports
final edge counts,
component-repair counts, degree summaries, and density/sparsity for each
adaptive-radius k.scale value.
## S3 method for class 'rknn_graphs' summary(object, ...)## S3 method for class 'rknn_graphs' summary(object, ...)
object |
An object of class |
... |
Additional arguments passed to or from other methods; currently unused. |
Invisibly returns a data frame with one row per graph and columns:
idx |
Position of the graph in the returned graph sequence. |
k |
The adaptive-radius |
n_vertices |
Number of graph vertices. |
n_ccomp |
Number of connected components in the final graph. |
n_ccomp_before_repair |
Number of components before component-MST repair. |
edges |
Final number of undirected edges. |
edges_before_pruning |
Number of edges before geometric pruning. |
edges_after_pruning |
Number of edges after geometric pruning and before optional component repair. |
mst_edges_added |
Number of component-MST repair edges added. |
mean_degree |
Average vertex degree in the final graph. |
min_degree |
Minimum vertex degree. |
median_degree |
Median vertex degree. |
max_degree |
Maximum vertex degree. |
max_degree_over_median |
Ratio of maximum to median degree, or
|
universal_vertices |
Number of vertices adjacent to every other vertex. |
density |
Final graph density. |
sparsity |
One minus graph density. |
X <- matrix(c(0, 1, 3, 4), ncol = 1) graphs <- create.rknn.graphs(X, k.values = seq.int(1, 2), radius.search = "all.pairs", graph.detail = "minimal", prune.method = "none") summary(graphs)X <- matrix(c(0, 1, 3, 4), ncol = 1) graphs <- create.rknn.graphs(X, k.values = seq.int(1, 2), radius.search = "all.pairs", graph.detail = "minimal", prune.method = "none") summary(graphs)
Summary method for vertex_geodesic_stats objects
## S3 method for class 'vertex_geodesic_stats' summary(object, ...)## S3 method for class 'vertex_geodesic_stats' summary(object, ...)
object |
A vertex_geodesic_stats object |
... |
Additional arguments passed to summary |
A summary of the vertex geodesic statistics
x <- data.frame( radius = c(0.2, 0.4, 0.6), rays = c(3, 5, 6), composite_geodesics = c(1, 2, 3), overlap_min = c(0.10, 0.15, 0.20), overlap_p05 = c(0.15, 0.20, 0.25), overlap_p25 = c(0.20, 0.25, 0.30), overlap_median = c(0.30, 0.40, 0.50), overlap_p75 = c(0.40, 0.50, 0.60), overlap_p95 = c(0.55, 0.65, 0.75), overlap_max = c(0.60, 0.70, 0.80), potential_pairs = c(3, 10, 15), composite_ratio = c(1/3, 0.2, 0.2), overlap_ratio = c(0.30, 0.40, 0.50) ) class(x) <- c("vertex_geodesic_stats", "data.frame") attr(x, "vertex") <- 7L summary(x)x <- data.frame( radius = c(0.2, 0.4, 0.6), rays = c(3, 5, 6), composite_geodesics = c(1, 2, 3), overlap_min = c(0.10, 0.15, 0.20), overlap_p05 = c(0.15, 0.20, 0.25), overlap_p25 = c(0.20, 0.25, 0.30), overlap_median = c(0.30, 0.40, 0.50), overlap_p75 = c(0.40, 0.50, 0.60), overlap_p95 = c(0.55, 0.65, 0.75), overlap_max = c(0.60, 0.70, 0.80), potential_pairs = c(3, 10, 15), composite_ratio = c(1/3, 0.2, 0.2), overlap_ratio = c(0.30, 0.40, 0.50) ) class(x) <- c("vertex_geodesic_stats", "data.frame") attr(x, "vertex") <- 7L summary(x)
Specify a circle geometry
synthetic.circle( radius = 1, angle.range = c(0, 2 * pi), ambient.dim = 2L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.circle( radius = 1, angle.range = c(0, 2 * pi), ambient.dim = 2L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
radius |
Circle radius. |
angle.range |
Admissible angular interval. |
ambient.dim |
Ambient dimension. |
frame, frame.algorithm, frame.matrix, offset
|
Frame parameters. |
A synthetic geometry component.
synthetic.circle(radius = 2, angle.range = c(0, pi))synthetic.circle(radius = 2, angle.range = c(0, pi))
Specify a helix geometry
synthetic.helix( pitch = 0.2, t.range = c(0, 2 * pi), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.helix( pitch = 0.2, t.range = c(0, 2 * pi), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
pitch |
Helix pitch. |
t.range |
Admissible parameter interval. |
ambient.dim |
Ambient dimension. |
frame, frame.algorithm, frame.matrix, offset
|
Frame parameters. |
A synthetic geometry component.
synthetic.helix(pitch = 0.25, t.range = c(0, pi))synthetic.helix(pitch = 0.25, t.range = c(0, pi))
Specify a point-line junction
synthetic.point.line.junction( point.location, line.origin, line.direction, line.range )synthetic.point.line.junction( point.location, line.origin, line.direction, line.range )
point.location |
Point location. |
line.origin, line.direction, line.range
|
Segment parameters. |
A two-stratum synthetic_stratified_geometry.
synthetic.point.line.junction(c(0, 0), c(0, 0), c(1, 0), c(0, 1))synthetic.point.line.junction(c(0, 0), c(0, 0), c(1, 0), c(0, 1))
Specify a quadform geometry
synthetic.quadform( intrinsic.dim, ambient.dim, forms = list(), frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.quadform( intrinsic.dim, ambient.dim, forms = list(), frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
intrinsic.dim |
Intrinsic dimension. |
ambient.dim |
Ambient dimension. |
forms |
List of finite symmetric quadratic-form matrices. |
frame |
Frame policy. |
frame.algorithm |
Versioned random-frame algorithm or |
frame.matrix |
Supplied orthonormal frame or |
offset |
Ambient offset or |
A synthetic geometry component.
synthetic.quadform(1L, 2L, forms = list(matrix(0.5)))synthetic.quadform(1L, 2L, forms = list(matrix(0.5)))
Clustered sampling specification
synthetic.sampling.clustered( cluster.count, observations.per.cluster, center.lower = -1, center.upper = 1, within.sd, algorithm = "centers.then.gaussian.offsets.v1" )synthetic.sampling.clustered( cluster.count, observations.per.cluster, center.lower = -1, center.upper = 1, within.sd, algorithm = "centers.then.gaussian.offsets.v1" )
cluster.count |
Number of clusters. |
observations.per.cluster |
Rows per cluster. |
center.lower, center.upper
|
Center box bounds. |
within.sd |
Within-cluster standard deviation. |
algorithm |
Versioned draw algorithm. |
A fixed-size synthetic sampling component.
synthetic.sampling.clustered(3L, 5L, within.sd = 0.1)synthetic.sampling.clustered(3L, 5L, within.sd = 0.1)
Dirichlet sampling with structural zeros
synthetic.sampling.dirichlet.zeros( concentration, zero.fraction, zero.parts, zero.row.policy = c("first", "random"), count.rounding = "round", algorithm = "normalized.gamma.v1" )synthetic.sampling.dirichlet.zeros( concentration, zero.fraction, zero.parts, zero.row.policy = c("first", "random"), count.rounding = "round", algorithm = "normalized.gamma.v1" )
concentration |
Scalar or part-wise Dirichlet concentration. |
zero.fraction |
Fraction of rows receiving structural zeros. |
zero.parts |
Part indices set to zero. |
zero.row.policy |
Row-selection policy. |
count.rounding |
Count rule. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.dirichlet.zeros( concentration = rep(1, 3), zero.fraction = 0.2, zero.parts = 1L )synthetic.sampling.dirichlet.zeros( concentration = rep(1, 3), zero.fraction = 0.2, zero.parts = 1L )
Gapped-uniform sampling specification
synthetic.sampling.gapped.uniform( intervals, allocation = c("multinomial", "fixed.proportion", "fixed.count"), probabilities = NULL, counts = NULL, rounding = c("largest.remainder", "floor.first.remainder.last"), order = c("draw", "ascending"), algorithm = "sequential.interval.runif.v1" )synthetic.sampling.gapped.uniform( intervals, allocation = c("multinomial", "fixed.proportion", "fixed.count"), probabilities = NULL, counts = NULL, rounding = c("largest.remainder", "floor.first.remainder.last"), order = c("draw", "ascending"), algorithm = "sequential.interval.runif.v1" )
intervals |
Two-column matrix of disjoint intervals. |
allocation |
Allocation policy. |
probabilities |
Optional allocation probabilities. |
counts |
Optional fixed counts. |
rounding |
Fixed-proportion rounding rule. |
order |
Ordering policy. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
intervals <- rbind(c(-1, -0.25), c(0.25, 1)) synthetic.sampling.gapped.uniform(intervals, probabilities = c(0.5, 0.5))intervals <- rbind(c(-1, -0.25), c(0.25, 1)) synthetic.sampling.gapped.uniform(intervals, probabilities = c(0.5, 0.5))
Deterministic interval-grid sampling specification
synthetic.sampling.grid.interval( lower, upper, endpoints = c("exclude.lower", "exclude.upper", "include.both") )synthetic.sampling.grid.interval( lower, upper, endpoints = c("exclude.lower", "exclude.upper", "include.both") )
lower, upper
|
Interval bounds. |
endpoints |
Endpoint convention. |
A deterministic synthetic sampling component.
synthetic.sampling.grid.interval(0, 2 * pi, endpoints = "exclude.lower")synthetic.sampling.grid.interval(0, 2 * pi, endpoints = "exclude.lower")
Versioned quadratic-surface sampling used by Geometry Lab
synthetic.sampling.quadform.lab( domain = c("square", "disk"), extent = 1, mode = c("uniform", "area", "grid", "center", "gap"), gap = 0.2, algorithm = "geometry.lab.v1" )synthetic.sampling.quadform.lab( domain = c("square", "disk"), extent = 1, mode = c("uniform", "area", "grid", "center", "gap"), gap = 0.2, algorithm = "geometry.lab.v1" )
domain |
Square or disk parameter domain. |
extent |
Positive domain radius or half-width, from 0.1 to 5. |
mode |
Parameter-uniform, surface-area, grid, center, or gap sampling. |
gap |
Empty strip half-width as a fraction of extent, from 0.01 to 0.8. |
algorithm |
The fixed version-1 draw and arithmetic policy. |
A sampling component for a canonical two-dimensional quadratic surface in three dimensions. Area sampling uses rejection sampling.
sampling <- synthetic.sampling.quadform.lab("disk", mode = "area") surface <- synthetic.quadform(2, 3, list(diag(c(1, -1)))) sample.synthetic.geometry(surface, sampling, 30, seed = 4101)$nsampling <- synthetic.sampling.quadform.lab("disk", mode = "area") surface <- synthetic.quadform(2, 3, list(diag(c(1, -1)))) sample.synthetic.geometry(surface, sampling, 30, seed = 4101)$n
Truncated-normal sampling specification
synthetic.sampling.truncated.normal( mean, sd, lower, upper, order = c("draw", "ascending"), algorithm = "inverse.cdf.v1" )synthetic.sampling.truncated.normal( mean, sd, lower, upper, order = c("draw", "ascending"), algorithm = "inverse.cdf.v1" )
mean, sd
|
Normal parameters. |
lower, upper
|
Truncation bounds. |
order |
Ordering policy. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.truncated.normal(0, 1, -2, 2)synthetic.sampling.truncated.normal(0, 1, -2, 2)
Uniform-box sampling specification
synthetic.sampling.uniform.box( lower, upper, order = c("draw", "ascending.first.coordinate"), algorithm = "column.major.runif.v1" )synthetic.sampling.uniform.box( lower, upper, order = c("draw", "ascending.first.coordinate"), algorithm = "column.major.runif.v1" )
lower, upper
|
Scalar or coordinate-wise bounds. |
order |
Row ordering policy. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.uniform.box(lower = c(-1, 0), upper = c(1, 2))synthetic.sampling.uniform.box(lower = c(-1, 0), upper = c(1, 2))
Uniform-disk sampling specification
synthetic.sampling.uniform.disk(radius = 1, algorithm = "radial.sqrt.v1")synthetic.sampling.uniform.disk(radius = 1, algorithm = "radial.sqrt.v1")
radius |
Disk radius. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.uniform.disk(radius = 2)synthetic.sampling.uniform.disk(radius = 2)
Uniform-interval sampling specification
synthetic.sampling.uniform.interval( lower, upper, order = c("draw", "ascending"), algorithm = "runif.v1" )synthetic.sampling.uniform.interval( lower, upper, order = c("draw", "ascending"), algorithm = "runif.v1" )
lower, upper
|
Interval bounds. |
order |
Ordering policy. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.uniform.interval(0, 1, order = "ascending")synthetic.sampling.uniform.interval(0, 1, order = "ascending")
Uniform-rectangle sampling specification
synthetic.sampling.uniform.rectangle( lower, upper, algorithm = "coordinate.sequential.runif.v1" )synthetic.sampling.uniform.rectangle( lower, upper, algorithm = "coordinate.sequential.runif.v1" )
lower, upper
|
Length-two coordinate bounds. |
algorithm |
Versioned draw algorithm. |
A synthetic sampling component.
synthetic.sampling.uniform.rectangle(c(-1, -2), c(1, 2))synthetic.sampling.uniform.rectangle(c(-1, -2), c(1, 2))
Specify a simplex geometry
synthetic.simplex(parts)synthetic.simplex(parts)
parts |
Number of compositional parts. |
A synthetic geometry component.
synthetic.simplex(parts = 3L)synthetic.simplex(parts = 3L)
Specify a sphere-cap geometry
synthetic.sphere.cap( radius = 2, footprint.radius = 1, ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.sphere.cap( radius = 2, footprint.radius = 1, ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
radius |
Sphere radius. |
footprint.radius |
Radius of the planar cap footprint. |
ambient.dim |
Ambient dimension. |
frame, frame.algorithm, frame.matrix, offset
|
Frame parameters. |
A synthetic geometry component.
synthetic.sphere.cap(radius = 2, footprint.radius = 1)synthetic.sphere.cap(radius = 2, footprint.radius = 1)
Assemble a stratified geometry
synthetic.stratified(strata, junctions = NULL)synthetic.stratified(strata, junctions = NULL)
strata |
Nonempty list of compatible |
junctions |
Optional data frame describing stratum boundary junctions. |
A draw-free synthetic geometry component.
point <- synthetic.stratum.point("point", c(0, 0)) line <- synthetic.stratum.segment("line", c(0, 1), c(0, 0), c(1, 0)) synthetic.stratified(list(point, line))point <- synthetic.stratum.point("point", c(0, 0)) line <- synthetic.stratum.segment("line", c(0, 1), c(0, 0), c(1, 0)) synthetic.stratified(list(point, line))
Specify a point stratum
synthetic.stratum.point(id, location)synthetic.stratum.point(id, location)
id |
Stable stratum identifier. |
location |
Finite ambient location. |
A draw-free synthetic_stratum.
synthetic.stratum.point("origin", c(0, 0))synthetic.stratum.point("origin", c(0, 0))
Specify a rectangle stratum
synthetic.stratum.rectangle(id, coordinate.ranges, origin, basis)synthetic.stratum.rectangle(id, coordinate.ranges, origin, basis)
id |
Stable stratum identifier. |
coordinate.ranges |
Two-row matrix of finite increasing ranges. |
origin |
Finite ambient origin. |
basis |
Orthonormal ambient-by-two basis. |
A draw-free synthetic_stratum.
synthetic.stratum.rectangle( "square", rbind(c(-1, 1), c(-1, 1)), c(0, 0), diag(2) )synthetic.stratum.rectangle( "square", rbind(c(-1, 1), c(-1, 1)), c(0, 0), diag(2) )
Specify a line-segment stratum
synthetic.stratum.segment(id, coordinate.range, origin, direction)synthetic.stratum.segment(id, coordinate.range, origin, direction)
id |
Stable stratum identifier. |
coordinate.range |
Finite increasing intrinsic range. |
origin |
Finite ambient origin. |
direction |
Unit ambient direction. |
A draw-free synthetic_stratum.
synthetic.stratum.segment("line", c(-1, 1), c(0, 0), c(1, 0))synthetic.stratum.segment("line", c(-1, 1), c(0, 0), c(1, 0))
Specify a torus-patch geometry
synthetic.torus.patch( major.radius = 1, minor.radius = 0.35, u.range = c(-pi/2, pi/2), v.range = c(-pi/2, pi/2), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.torus.patch( major.radius = 1, minor.radius = 0.35, u.range = c(-pi/2, pi/2), v.range = c(-pi/2, pi/2), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
major.radius, minor.radius
|
Torus radii. |
u.range, v.range
|
Admissible angular intervals. |
ambient.dim |
Ambient dimension. |
frame, frame.algorithm, frame.matrix, offset
|
Frame parameters. |
A synthetic geometry component.
synthetic.torus.patch(major.radius = 2, minor.radius = 0.5)synthetic.torus.patch(major.radius = 2, minor.radius = 0.5)
This preserves the legacy gflow parameterization:
x = scale * sin(t) + 2 * sin(2*t),
y = scale * cos(t) - 2 * cos(2*t), and
z = -scale * sin(3*t).
synthetic.trefoil( scale = 1, t.range = c(0, 2 * pi), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )synthetic.trefoil( scale = 1, t.range = c(0, 2 * pi), ambient.dim = 3L, frame = c("canonical", "random.orthonormal", "supplied"), frame.algorithm = NULL, frame.matrix = NULL, offset = NULL )
scale |
Scale applied to the first harmonic and third coordinate. |
t.range |
Admissible parameter interval. |
ambient.dim |
Ambient dimension. |
frame, frame.algorithm, frame.matrix, offset
|
Frame parameters. |
A synthetic geometry component.
synthetic.trefoil(scale = 0.5, t.range = c(0, pi))synthetic.trefoil(scale = 0.5, t.range = c(0, pi))
Validates whether a given vertex packing is maximal and correctly satisfies the distance constraints. A packing is valid if all vertices are separated by at least the specified radius, and is maximal if no additional vertices can be added without violating this constraint.
validate.maximal.packing( adj.list, length.list, packing.vertices, max.packing.radius )validate.maximal.packing( adj.list, length.list, packing.vertices, max.packing.radius )
adj.list |
A list where each element is a vector of adjacent vertex indices (1-based) for the corresponding vertex. |
length.list |
A list where each element is a vector of edge weights
corresponding to the adjacencies in |
packing.vertices |
An integer vector of vertex indices (1-based) that form the packing to be validated. |
max.packing.radius |
A numeric value representing the minimum distance that should separate any two vertices in the packing. |
This function performs two key validations:
Packing Property: Verifies that all vertices in the
packing are separated by at least max.packing.radius.
Maximality: Verifies that no additional vertex can be added to the packing without violating the packing property.
The function uses the igraph package to compute shortest path
distances between vertices using Dijkstra's algorithm.
A list with class "packing_validation" containing validation results:
valid |
Logical indicating whether the packing satisfies the distance constraint |
min.packing.distance |
The minimum distance found between any two packing vertices |
max.coverage.distance |
The maximum distance from any non-packing vertex to its nearest packing vertex |
violations |
A data frame containing details of any violations found, or NULL if none. Contains columns: type, vertex1, vertex2, distance |
is.maximal |
Logical indicating whether the packing is maximal (no vertices can be added) |
potential.additions |
Integer vector of vertex indices that could potentially be added to the packing if it's not maximal, or NULL if maximal |
adj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) packing <- c(1, 3, 5) radius <- 2 result <- validate.maximal.packing(adj.list, length.list, packing, radius) result$valid result$is.maximaladj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) packing <- c(1, 3, 5) radius <- 2 result <- validate.maximal.packing(adj.list, length.list, packing, radius) result$valid result$is.maximal
Validate a geometry specification or its latent coordinates
validate.synthetic.geometry(geometry, latent = NULL)validate.synthetic.geometry(geometry, latent = NULL)
geometry |
A geometry component constructed by this package. |
latent |
Optional latent coordinate matrix. |
With no latent input, the unchanged geometry invisibly. Otherwise, the validated latent coordinates as a double matrix.
validate.synthetic.geometry(synthetic.circle(), matrix(c(0, pi), ncol = 1))validate.synthetic.geometry(synthetic.circle(), matrix(c(0, pi), ncol = 1))
Validate a point-sampling specification and geometric support
validate.synthetic.sampling(sampling, geometry = NULL)validate.synthetic.sampling(sampling, geometry = NULL)
sampling |
A sampling component constructed by this package. |
geometry |
Optional geometry component for support checks. |
The unchanged sampling specification, invisibly.
validate.synthetic.sampling(synthetic.sampling.uniform.disk(0.5), synthetic.sphere.cap())validate.synthetic.sampling(synthetic.sampling.uniform.disk(0.5), synthetic.sphere.cap())
A convenience function to verify the correctness of a maximal
packing created using the create.maximal.packing function.
This function validates both the packing property (minimum separation
distance) and maximality (no vertices can be added).
verify.maximal.packing(packing.result, verbose = TRUE)verify.maximal.packing(packing.result, verbose = TRUE)
packing.result |
The result returned by
|
verbose |
Logical indicating whether to print detailed validation results. Default is TRUE. |
This function takes the output of create.maximal.packing
and verifies two key properties:
The packing vertices are all separated by at least
max_packing_radius
The packing is maximal (no more vertices can be added without violating the distance constraint)
When \code{verbose = TRUE}, the function prints:
\itemize{
\item Graph diameter
\item Packing radius used
\item Number of vertices in the packing
\item Minimum distance between packing vertices
\item Maximum coverage distance
\item Validity and maximality status
\item Any violations or potential additions (if applicable)
}
A logical value: TRUE if the packing is both valid (satisfies the distance constraint) and maximal (no vertices can be added), FALSE otherwise.
create.maximal.packing,
validate.maximal.packing
adj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) result <- create.maximal.packing(adj.list, length.list, grid.size = 2) verify.maximal.packing(result, verbose = FALSE)adj.list <- list(c(2), c(1, 3), c(2, 4), c(3, 5), c(4)) length.list <- list(c(1), c(1, 1), c(1, 1), c(1, 1), c(1)) result <- create.maximal.packing(adj.list, length.list, grid.size = 2) verify.maximal.packing(result, verbose = FALSE)
Extract Vertices from a Graph Result
vertices(object, ...)vertices(object, ...)
object |
Object from which vertices should be extracted. |
... |
Additional arguments passed to methods. |
Object-specific vertex indices.
chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) vertices(extrema, extrema$labels[[1]])chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) vertices(extrema, extrema$labels[[1]])
Extract a Local-Extremum Neighborhood
## S3 method for class 'local_extrema' vertices(object, label, include.center = TRUE, ...)## S3 method for class 'local_extrema' vertices(object, label, include.center = TRUE, ...)
object |
Object from which vertices should be extracted. |
label |
Character scalar identifying an extremum in |
include.center |
Logical; include the extremum vertex itself. |
... |
Additional arguments passed to methods. |
An integer vector of one-based vertex indices in the selected extremum's stored neighborhood, optionally excluding its center.
chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) vertices(extrema, extrema$labels[[1]])chain <- create.graph("chain", n = 5) extrema <- detect.local.extrema(graph.adjacency(chain), graph.lengths(chain), y = c(1, 3, 1, 2, 0), max.radius = 1, min.neighborhood.size = 2) vertices(extrema, extrema$labels[[1]])
Prune Long Edges in a Weighted Graph
wgraph.prune.long.edges( adj.list, length.list, alt.path.len.ratio.thld, use.total.length.constraint = TRUE, verbose = FALSE )wgraph.prune.long.edges( adj.list, length.list, alt.path.len.ratio.thld, use.total.length.constraint = TRUE, verbose = FALSE )
adj.list |
A graph adjacency list. |
length.list |
Edge-length list matching |
alt.path.len.ratio.thld |
Alternative-path threshold. |
use.total.length.constraint |
If |
verbose |
Logical progress flag. |
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.
graph <- list(c(2L, 3L), c(1L, 3L), c(1L, 2L)) lengths <- list(c(1, 2), c(1, 1), c(2, 1)) graph.adjacency(wgraph.prune.long.edges(graph, lengths, alt.path.len.ratio.thld = 1.1))graph <- list(c(2L, 3L), c(1L, 3L), c(1L, 2L)) lengths <- list(c(1, 2), c(1, 1), c(2, 1)) graph.adjacency(wgraph.prune.long.edges(graph, lengths, alt.path.len.ratio.thld = 1.1))