Merge Two Specified Local Extrema with Trajectory Preservation
Source:R/merge_two_extrema.R
merge.two.extrema.RdMerges two specific local extrema of the same type by absorbing one basin into another, creating a unified hierarchical basin structure. This function enables manual expert-based simplification while preserving complete gradient flow information including predecessors and terminal extrema for downstream analysis.
Arguments
- x
An object of class
"basins_of_attraction"returned bycompute.basins.of.attractionwith gradient basin structures including predecessors and terminal extrema. The basin lists (lmax_basinsandlmin_basins) must be named with extremum labels.- y
Optional alias for
winner.label(kept for backward compatibility).- winner.label
Character string or numeric value specifying the label of the winning basin that will absorb the other basin. This label must appear as a name in the appropriate basin list (e.g., in
names(x$basins$lmin_basins)for minima).- loser.label
Character string or numeric value specifying the label of the losing basin to be absorbed. This basin will be removed from the basin list, its vertices incorporated into the winner's basin, and its complete structure preserved in the winner's absorbed_extrema list.
- verbose
Logical; if TRUE, print additional merge diagnostics.
- ...
Additional arguments (currently ignored).
Value
An object of class "basins_of_attraction" with the same structure
as the input x but with the specified basins merged. The object
contains:
- lmin_basins
Named list of basin structures for local minima (modified if
extrema.type = "min"). The winner basin now includes anabsorbed_extremalist with the loser's complete structure. The loser's entry is removed from the list.- lmax_basins
Named list of basin structures for local maxima (modified if
extrema.type = "max"), with the same hierarchical structure.- n_vertices
Total number of vertices in the graph.
- y
Copy of the input function values.
- merge.info
List containing information about merge operations. If previous merges were performed, this list accumulates information from all operations. For the current merge, the following components are added or updated:
- operations
Data frame with one row per merge operation.
- absorbed.extrema
Data frame tracking all absorbed extrema across all merge operations.
Details
The merging problem arises when visual examination of the response surface or consideration of the physical process suggests that two nearby local extrema should be treated as a single feature. Perhaps the separation between them results from noise in the data, or perhaps the analyst judges based on domain knowledge that the distinction lacks practical significance. In such cases, we wish to consolidate the two basins while preserving complete information about the operation for downstream analysis.
We begin by identifying the two extrema to merge through their basin labels,
which provide unambiguous references to specific basins. The basin lists
(lmax_basins and lmin_basins) are named with these labels,
enabling direct access without requiring auxiliary lookup structures. The user
designates one extremum as the winner, which will represent the merged feature,
while the other becomes the loser whose basin will be absorbed. This choice may
reflect which extremum has the more extreme function value, which lies in a more
central location, or which better represents the feature according to domain expertise.
The merged basin is constructed as the set-theoretic union of the two original basins. All vertices from the loser's basin are incorporated into the winner's basin structure, extending the region of influence. The winner's extremum vertex and function value remain as the representative for the merged basin, while the basin vertex set expands to include all vertices from both basins.
Critically, this implementation preserves the complete gradient flow structure of the absorbed basin. The loser's original basin structure, including its predecessor map and terminal extrema, is stored hierarchically within the winner's basin. This enables reconstruction of gradient trajectories that terminate at the absorbed extremum, which proves essential for gradient flow cell analysis and monotonicity testing. Additionally, we compute absorption metadata including the geodesic path connecting the loser to the winner and the height of the monotonicity barrier crossed. This information quantifies the "spuriousness" of the absorbed extremum and supports flexible downstream analysis strategies.
The winner's terminal extrema are updated to remove the loser if it was previously a terminal extremum of the winner's basin. This maintains consistency in the gradient flow cell structure, as the loser no longer exists as an independent extremum but is preserved as an absorbed substructure.
We preserve the hop distance structure from the winner's basin for its original vertices. For vertices absorbed from the loser's basin, we assign a hop distance one greater than the maximum hop distance in the winner's original basin. This convention maintains the breadth-first search structure while clearly indicating which vertices came from the absorbed basin.
The function returns a modified basins of attraction object maintaining the same structure as the input but with hierarchical absorption tracking. Complete metadata about the operation appears in a merge.info component, documenting which extremum was absorbed, both extrema's vertices and function values, the y-barrier crossed, and how the basin size changed. This hierarchical structure supports flexible analysis strategies ranging from strict monotonicity testing (respecting absorbed extrema as endpoints) to permissive approaches (extending trajectories through absorbed extrema).
The user may apply this function sequentially to merge multiple pairs of extrema, building up a progressively simplified basin structure through a series of pairwise operations. Each merge operation preserves information about previous merges in both the basin-level absorbed_extrema lists and the global merge.info component, allowing complete reconstruction of the simplification history.
Examples
if (FALSE) { # \dontrun{
# Compute refined basins with named lists
result <- compute.gfc(adj.list, edgelen.list, fitted.values)
basins <- result$basins
# Examine the summary to identify basins to merge
print(result$summary[result$summary$type == "min", ])
# Merge two minima with trajectory preservation
# Labels are now directly accessible as names
merged.basins <- merge.two.extrema(basins,
winner.label = "42",
loser.label = "37")
# Examine merge information
print(merged.basins$merge.info$operations)
# Access absorbed basin structure
winner.basin <- merged.basins$lmin_basins[["42"]]
if (length(winner.basin$absorbed_extrema) > 0) {
absorbed <- winner.basin$absorbed_extrema[["37"]]
cat("Absorbed extremum:", absorbed$vertex, "\n")
cat("Y barrier:", absorbed$absorption_info$y_barrier, "\n")
}
} # }