Compute Gradient Flow Complex Using Trajectory-First Approach
Source:R/gfc_flow.R
compute.gfc.trajectory.RdComputes basins of attraction by tracing gradient flow trajectories rather
than growing basins outward from extrema. This approach treats gradient flow
lines as the fundamental geometric primitives, with basins emerging as the
collection of vertices along trajectories sharing the same endpoints.
compute.gfc.flow() is kept as a backward-compatible deprecated alias.
Usage
compute.gfc.trajectory(
adj.list,
weight.list,
y,
density = NULL,
modulation = c("CLOSEST", "NONE", "DENSITY", "EDGELEN", "DENSITY_EDGELEN"),
edge.length.quantile.thld = 0.9,
long.edge.fallback = c("allow_and_flag", "allow", "forbid"),
apply.relvalue.filter = TRUE,
min.rel.value.max = 1.1,
max.rel.value.min = 0.9,
apply.maxima.clustering = TRUE,
apply.minima.clustering = TRUE,
max.overlap.threshold = 0.15,
min.overlap.threshold = 0.15,
apply.geometric.filter = TRUE,
p.mean.nbrs.dist.threshold = 0.9,
p.mean.hopk.dist.threshold = 0.9,
p.deg.threshold = 0.9,
min.basin.size = 10L,
min.n.trajectories = 0L,
hop.k = 2L,
store.trajectories = TRUE,
max.trajectory.length = 10000L,
symmetric.seeding = TRUE,
tie.breaking = TRUE,
verbose = FALSE
)
compute.gfc.flow(
adj.list,
weight.list,
y,
density = NULL,
modulation = c("CLOSEST", "NONE", "DENSITY", "EDGELEN", "DENSITY_EDGELEN"),
edge.length.quantile.thld = 0.9,
long.edge.fallback = c("allow_and_flag", "allow", "forbid"),
apply.relvalue.filter = TRUE,
min.rel.value.max = 1.1,
max.rel.value.min = 0.9,
apply.maxima.clustering = TRUE,
apply.minima.clustering = TRUE,
max.overlap.threshold = 0.15,
min.overlap.threshold = 0.15,
apply.geometric.filter = TRUE,
p.mean.nbrs.dist.threshold = 0.9,
p.mean.hopk.dist.threshold = 0.9,
p.deg.threshold = 0.9,
min.basin.size = 10L,
min.n.trajectories = 0L,
hop.k = 2L,
store.trajectories = TRUE,
max.trajectory.length = 10000L,
symmetric.seeding = TRUE,
tie.breaking = TRUE,
verbose = FALSE
)Arguments
- adj.list
List of integer vectors. Each element
adj.list[[i]]contains the 1-based indices of vertices adjacent to vertexi.- weight.list
List of numeric vectors. Each element
weight.list[[i]]contains the edge weights (distances) corresponding toadj.list[[i]].- y
Numeric vector of function values at each vertex.
- density
Optional numeric vector of density values at each vertex. Required if
modulationis"DENSITY"or"DENSITY_EDGELEN". Ignored for"CLOSEST".- modulation
Character string specifying gradient modulation strategy. One of
"NONE","DENSITY","EDGELEN","DENSITY_EDGELEN", or"CLOSEST". Default is"CLOSEST". See Details for descriptions of each option.- edge.length.quantile.thld
Numeric in (0,1]. Quantile threshold for edge length filtering during trajectory computation. For non-
"CLOSEST"modulations, edges longer than this quantile are not traversed. For"CLOSEST",long.edge.fallbackcontrols what happens when all improving neighbors exceed the threshold. Default is 0.9.- long.edge.fallback
Character policy used by
"CLOSEST"when no improving edge is at or below the edge-length threshold."allow_and_flag"preserves the historical shortest-improving-edge fallback and marks the returned telemetry for attention;"allow"preserves the same path without the attention flag; and"forbid"makes the threshold hard and terminates the trajectory at that vertex. All policies report observed fallback counts. Default is"allow_and_flag".- apply.relvalue.filter
Logical. Whether to filter extrema by relative value. Default is
TRUE.- min.rel.value.max
Numeric. Minimum relative value (value/mean(y)) for retaining maxima. Default is 1.1.
- max.rel.value.min
Numeric. Maximum relative value for retaining minima. Default is 0.9.
- apply.maxima.clustering
Logical. Whether to cluster and merge maxima based on basin overlap. Default is
TRUE.- apply.minima.clustering
Logical. Whether to cluster and merge minima. Default is
TRUE.- max.overlap.threshold
Numeric in \([0,1]\). Overlap distance threshold for merging maxima basins. Default is 0.15.
- min.overlap.threshold
Numeric in \([0,1]\). Overlap distance threshold for merging minima basins. Default is 0.15.
- apply.geometric.filter
Logical. Whether to filter by geometric characteristics. Default is
TRUE.- p.mean.nbrs.dist.threshold
Numeric in \([0,1]\). Percentile threshold for mean neighbor distance (maxima only). Default is 0.9.
- p.mean.hopk.dist.threshold
Numeric in \([0,1]\). Percentile threshold for hop-k distance. Default is 0.9.
- p.deg.threshold
Numeric in \([0,1]\). Degree percentile threshold. Default is 0.9.
- min.basin.size
Integer. Minimum basin size to retain. Default is 10.
- min.n.trajectories
Integer. Minimum number of basin trajectories to retain the basin. Default is 0.
- hop.k
Integer. Hop distance for computing summary statistics. Default is 2.
- store.trajectories
Logical. Whether to store full trajectory information in the result. Default is
TRUE.- max.trajectory.length
Integer. Maximum trajectory length (vertices) before stopping. Prevents infinite loops in degenerate cases. Default is 10000.
- symmetric.seeding
Logical. If
TRUE, additionally seed trajectories from local maxima (descending) to make the trajectory seeding symmetric with respect to minima and maxima.- tie.breaking
Logical. If
TRUE, preserve the historical behavior of adding tiny random noise to globally tied response values before flow construction. Set toFALSEwhen connected plateaus have already been contracted and only nonadjacent equal values remain.- verbose
Logical. Whether to print progress messages. Default is
FALSE.
Value
A list of class "gfc.flow" containing basin and trajectory
information. The long.edge.fallback component records the selected
policy, per-vertex ascent/descent fallback and blocked-step flags,
trajectory step counts, and basin source-vertex counts. See the original
function documentation for full details.
Details
The algorithm proceeds as follows:
Identify all local minima using neighborhood comparison
From each local minimum, trace an ascending trajectory following the selected modulation strategy until reaching a local maximum
Optionally (default), seed local maxima with descending trajectories and map them into canonical min-to-max orientation
Assign trajectory vertices to both endpoint basins
For any unvisited vertices, trace both ascending and descending trajectories, joining them at that vertex
Apply the filtering/merging pipeline (relative value filtering, overlap-based clustering, geometric filtering)
Retained extrema are numbered by descending basin size.
Modulation Options
The modulation parameter controls how the next vertex is selected
at each step of the trajectory:
"NONE"Standard steepest ascent/descent. Selects the neighbor maximizing the function difference \(|y(u) - y(v)|\). This is the classical gradient flow approach but may cause basin jumping near separatrices when adjacent basins have very different gradient magnitudes.
"DENSITY"Density-modulated flow. Multiplies the gradient by vertex density to prefer higher-density regions: \(\rho(u) \cdot \Delta y\).
"EDGELEN"Edge-length modulated flow. Multiplies the gradient by a KDE-based edge length weight that down-weights atypically long edges: \(w(d(v,u)) \cdot \Delta y\). This prevents basin jumping through outlier edges but still uses a multiplicative score that can be dominated by extreme gradient contrasts.
"DENSITY_EDGELEN"Combined density and edge-length modulation.
"CLOSEST"Lexicographic closest ascending neighbor rule. This implements a two-level selection:
Filter to ascending neighbors \(u\) satisfying \(y(u) > y(v)\).
Among those ascending neighbors, select the one with minimum edge distance \(d(v,u)\).
Equal edge lengths are resolved by the smaller target-vertex identifier. This approach minimizes basin-jumping errors by taking the smallest step that makes progress. Unlike multiplicative scores, the lexicographic rule cannot be overridden by extreme gradient contrasts between adjacent basins. When every improving edge exceeds the standard edge-length threshold,
long.edge.fallbackdetermines whether the shortest such edge is used.
Lifecycle
This exported name is retired and always raises a
gflow_basin_lifecycle_error. Historical arguments and return descriptions
below document archived calls, not a runnable estimator. Use
create.basin.complex with method = "trajectory_flow"
and translate controls explicitly. See gflow-migration.
This exported name is retired and always raises a
gflow_basin_lifecycle_error. Historical arguments and return descriptions
below document archived calls, not a runnable estimator. Use
create.basin.complex with method = "trajectory_flow"
and translate controls explicitly. See gflow-migration.
See also
compute.gfc for the extrema-first approach
Examples
if (FALSE) { # \dontrun{
## Create a simple graph
adj.list <- list(
c(2L, 3L),
c(1L, 3L, 4L),
c(1L, 2L, 4L),
c(2L, 3L)
)
weight.list <- list(
c(1.0, 1.5),
c(1.0, 1.2, 1.0),
c(1.5, 1.2, 1.0),
c(1.0, 1.0)
)
y <- c(0.5, 1.2, 0.8, 2.0)
## Standard steepest ascent (may have basin jumping issues)
result.steep <- compute.gfc.trajectory(adj.list, weight.list, y,
modulation = "NONE")
## Edge-length modulated (reduces but doesn't eliminate jumping)
result.edgelen <- compute.gfc.trajectory(adj.list, weight.list, y,
modulation = "EDGELEN")
## Closest ascending neighbor (lexicographic, no tuning needed)
result.closest <- compute.gfc.trajectory(adj.list, weight.list, y,
modulation = "CLOSEST")
} # }