This traces the primary grip() engine, including the
coarse-level global-repulsion term used by the quality-first default layout.
For backwards-compatible traces of the historical local-force wrapper, use
trace.legacy.grip().
Usage
trace.grip(
edges = NULL,
n = NULL,
adj_list = NULL,
weight_list = NULL,
edge_weights = NULL,
dim = 3,
placement = c("barycenter", "circle"),
preset = NULL,
rounds = 160,
final_rounds = 384,
num_init = 24,
num_nbrs = 20,
r = 0.03,
s = 7.5,
repulsion_factor = 2.5,
coarse_repulsion_factor = 1.5,
coarse_repulsion_sample = 16,
coarse_repulsion_exact_below = 64,
final_anchor_factor = 0,
final_move_scale_after_first = 1,
final_mode = c("fr", "kk_repulse"),
insertion_anchor_count = 3,
insertion_anchor_scope = c("any_higher", "prev_misf"),
insertion_anchor_strategy = c("first", "distance_band", "balanced_band", "spread_prev"),
level0_insertion_mode = c("inherit", "barycenter", "least_squares"),
level0_anchor_count = insertion_anchor_count,
level0_local_kk_steps = 3,
lgkk_polish_rounds = 0L,
lgkk_multiscale_rounds = 0L,
lgkk_rounds_coarse = NULL,
lgkk_rounds_pre_final = NULL,
lgkk_rounds_final = NULL,
lgkk_local_nbrs = 20L,
lgkk_landmark_count = 8L,
lgkk_multiscale_scope = c("all", "coarse"),
lgkk_active_limit = 4096L,
tinit_factor = 6,
seed = 6,
trace = c("round", "level"),
trace.every = 1,
diagnostics = c("none", "light", "full"),
target_coords = NULL,
diagnostic_sample_size_nonedge = 1000L,
diagnostic_sample_size_stress = 500L,
diagnostic_nonedge_seed = 1L,
diagnostic_stress_seed = 1L
)Arguments
- edges
Two-column integer matrix of edges (1-based vertex ids).
- n
Number of vertices.
- adj_list
Adjacency list (1-based) for undirected graphs.
- weight_list
Optional parallel list of edge weights (edge lengths). If NULL, all edges are treated as weight 1. All weights must be finite and strictly positive.
- edge_weights
Optional vector of edge weights for
edges. All weights must be finite and strictly positive.- dim
Layout dimension (2 or 3). Default is 3.
- placement
Initial placement strategy. "circle" is only used for 2D.
- preset
Optional tuning preset.
NULLuses the quality-first defaults."carpet"applies a preset tuned for Sierpinski-carpet-like graphs and validated on carpet levels 3 and 4."mesh"applies a preset tuned for rectangular lattice graphs and validated on 8x8 and 12x12 mesh layouts."torus"applies a preset tuned for 3D torus layouts and validated on torus sizes from 8x8 through 20x20."tree"applies a preset tuned for symmetric force-directed layouts of tree-like graphs and validated on binary trees of depths 5 and 6. Presets only fill in tuning arguments that you did not supply explicitly.- rounds
Initial rounds for refinement.
- final_rounds
Final rounds for refinement.
- num_init
Number of initial vertices in the coarsest level.
- num_nbrs
Maximum number of graph-distance neighbors retained for local refinement at each filtration level.
- r
Main local temperature adaptation rate in
[0, 1].- s
Non-negative boost factor applied when successive displacements have a consistent direction.
- repulsion_factor
Non-negative multiplier applied to GRIP's finest-level repulsive force scale.
- coarse_repulsion_factor
Non-negative multiplier applied to the extra coarse-level active-set repulsion term.
0disables that extra term.- coarse_repulsion_sample
Positive integer sample size used to approximate active-set-wide repulsion on larger coarse levels.
- coarse_repulsion_exact_below
Positive integer threshold. When the active set size is at most this value, the coarse repulsion is computed exactly against all currently active vertices instead of being sampled.
- final_anchor_factor
Non-negative multiplier for an anchor term that pulls the final FR stage back toward the pre-final full-graph layout. `0` disables the anchor and preserves the current behavior.
- final_move_scale_after_first
Scalar in `[0, 1]` applied to the final FR displacement after the first finest-level round. Values below `1` damp later full-graph movement while keeping the first FR round unchanged.
- final_mode
Final full-graph refinement mode.
"fr"keeps the current Fruchterman-Reingold-style final stage."kk_repulse"uses a KK-style local distance-matching update with explicit active-set repulsion instead of the final FR phase.- insertion_anchor_count
Positive integer number of anchor vertices used during multiscale insertion on non-initial MISF refinement levels. This is the closest current implementation to a global
K_mishparameter.- insertion_anchor_scope
Anchor-eligibility rule used during multiscale insertion.
"any_higher"matches the historical GRIP behavior and allows anchors from any already placed higher MISF level."prev_misf"restricts anchors to the immediately previous MISF level only.- insertion_anchor_strategy
Anchor-selection rule used during multiscale insertion.
"first"keeps the historical first-anchors-found BFS behavior."distance_band"keeps exploring until theK_mish-th anchor distance band is exhausted, then places the new vertex from that less order-sensitive anchor pool."balanced_band"uses the same band expansion, then explicitly selects a subset whose centroid stays centered in the candidate cloud while remaining geometrically spread out."spread_prev"is a symmetry-oriented band strategy intended to be paired withinsertion_anchor_scope = "prev_misf"; it selects anchors with broad angular and geometric coverage before placement.- level0_insertion_mode
Level-0 insertion placement override used only when the finest filtration level is first populated.
"inherit"keeps the current GRIP behavior."barycenter"disables the 2D circle heuristic at level 0 and uses barycentric anchor placement."least_squares"uses a multi-anchor least-squares distance fit at level 0 before any local micro-polish.- level0_anchor_count
Positive integer number of already placed anchors to collect for level-0 insertion experiments. By default this inherits
insertion_anchor_count. The legacy behavior uses 3.- level0_local_kk_steps
Non-negative integer number of tiny local KK micro-polish steps applied immediately after each level-0 insertion. The legacy behavior uses 3.
- lgkk_polish_rounds
Non-negative integer number of experimental landmark-geodesic KK polish iterations applied after the main GRIP solve.
0disables the polish.- lgkk_multiscale_rounds
Non-negative integer number of compiled landmark-geodesic KK refinement rounds applied inside the multiscale solver after each eligible MISF level completes its standard GRIP rounds. This legacy shared budget is used as a fallback when any of the more specific per-stage budgets below are left
NULL.- lgkk_rounds_coarse
Optional non-negative integer number of compiled LGKK rounds applied on coarse MISF levels with
misf_level > 1. WhenNULL, this falls back tolgkk_multiscale_rounds.- lgkk_rounds_pre_final
Optional non-negative integer number of compiled LGKK rounds applied on the last coarse level just before the full graph is opened (
misf_level == 1). WhenNULL, this falls back tolgkk_multiscale_rounds.- lgkk_rounds_final
Optional non-negative integer number of compiled LGKK rounds applied after the full graph level completes its standard GRIP rounds (
misf_level == 0). WhenNULL, this falls back tolgkk_multiscale_rounds.- lgkk_local_nbrs
Number of nearest graph-metric neighbors retained per vertex in the LGKK sparse local set when either LGKK stage is enabled.
- lgkk_landmark_count
Number of farthest-point landmarks retained per vertex in the LGKK sparse long-range set when either LGKK stage is enabled.
- lgkk_multiscale_scope
Scope for the compiled multiscale LGKK stage.
"all"applies it after every eligible MISF level, including the final full-graph level."coarse"applies it only on coarse levels.- lgkk_active_limit
Positive integer upper bound on the active-set size for compiled multiscale LGKK cache construction. Levels larger than this skip the multiscale LGKK stage.
- tinit_factor
Initial temperature factor.
- seed
Optional RNG seed for reproducibility. If NULL, uses current time.
- trace
Snapshot granularity.
"round"records the coarsest initialization, each level start, everytrace.everycompleted rounds, and the final layout."level"records the coarsest initialization, everytrace.everyth level start, and the final layout.- trace.every
Positive integer thinning factor for recorded rounds or levels. Initial and final snapshots are always included.
- diagnostics
Optional per-frame diagnostic mode.
"none"skips extra scoring,"light"appends lightweight shape diagnostics, and"full"also computes sampled stress on each traced frame.- target_coords
Optional numeric target coordinate matrix used to append per-frame Procrustes RMSE diagnostics. It must have `n` rows and `dim` columns.
- diagnostic_sample_size_nonedge
Positive integer sample size used for per-frame non-edge separation diagnostics when
diagnostics != "none".- diagnostic_sample_size_stress
Positive integer sample size used for per-frame sampled stress when
diagnostics = "full".- diagnostic_nonedge_seed
RNG seed base used for per-frame non-edge separation diagnostics.
- diagnostic_stress_seed
RNG seed base used for per-frame sampled stress diagnostics.
Value
A list with final, frames, meta, trace,
trace.every, canonical stage_trace and stage_data,
and optionally diagnostics and lgkk.polish. final is
the final coordinate matrix. frames is a list of coordinate
matrices with NA rows for vertices that have not yet been
introduced by GRIP. meta is a data frame describing each frame with
columns frame, phase, level_index, misf_level,
round_in_level, and active_vertices. stage_trace and
stage_data lift the raw frames onto the shared MISF stage schema
used by the geodesic multiscale methods, with canonical states such as
seed, initial_placement, top_level,
insertion, refinement, and final_polish. When
diagnostics are requested, diagnostics is a data frame parallel to
meta that appends per-frame quality metrics such as
edge.length.cv, sampled.nonedge.sep.ratio, and optional
procrustes.rmse.
Examples
edges <- cbind(1:5, 2:6)
tr <- trace.grip(edges, n = 6, dim = 2,
placement = "barycenter",
rounds = 3, final_rounds = 2,
num_init = 3, num_nbrs = 4,
trace = "level",
trace.every = 1,
diagnostics = "light",
seed = 1)
tr$diagnostics
#> frame phase level_index misf_level round_in_level active_vertices
#> 1 1 init 1 1 0 3
#> 2 2 level_start 2 0 0 6
#> 3 3 final 2 0 2 6
#> active.edges edge.length.cv median.edge.length sampled.nonedge.sep.ratio
#> 1 0 NA NA NA
#> 2 5 0.6138489 40.35679 0.9923493
#> 3 5 0.3423293 30.12023 1.5678969
#> sampled.stress procrustes.rmse
#> 1 NA NA
#> 2 NA NA
#> 3 NA NA