Skip to contents

edge.kk() is the edge-restricted Kamada–Kawai local repair operator for the experimental GMDS layout program. Earlier notes called this operator edge-gKK or edge-isometric GMDS; edge-KK is the preferred name because the objective is restricted to graph edges rather than all graph-geodesic pairs. It minimizes weighted edge-length stress $$ \frac{1}{2}\sum_{(i,j)\in E} k_{ij} \left(\|z_i-z_j\|_2 - s w_{ij}\right)^2 $$ using deterministic gradient descent with Armijo backtracking. The default density.mix.schedule runs a continuation from density-weighted stiffnesses toward uniform stiffnesses.

Usage

edge.kk(
  coords = NULL,
  prepared = NULL,
  edges = NULL,
  n = NULL,
  adj.list = NULL,
  weight.list = NULL,
  edge.weights = NULL,
  dim = 2L,
  init = c("classical_mds", "metric_mds", "weighted_grip", "random"),
  weighted.grip.args = list(),
  stiffness.method = c("density", "uniform", "distance_power"),
  stiffness.transform = c("identity", "sqrt", "log"),
  density.mix.schedule = c(0, 0.25, 0.5, 0.75, 1),
  bandwidth = NULL,
  density.n = 512L,
  distance.power = 0,
  stiffness.floor = 0,
  stiffness.ceiling = Inf,
  scale.mode = c("profiled", "identity", "fixed_initial", "user"),
  scale = NULL,
  max.iter = 50L,
  initial.step = 1,
  step.shrink = 0.5,
  armijo.factor = 1e-04,
  grad.tol = 1e-08,
  min.step = 1e-08,
  edge.length.epsilon = 1e-08,
  distance.floor = 1e-08,
  recenter = TRUE,
  return.trace = TRUE,
  diagnostics = TRUE,
  seed = 1L,
  engine = c("cpp", "R")
)

Arguments

coords

Optional starting coordinates. If omitted, init is used.

prepared

Optional object returned by prepare.edge.kk(), prepare.graph.geodesic.mds() or prepare.geodesic.kk(). Edge-only objects from prepare.edge.kk() report only edge diagnostics; all-pairs GMDS path and chord diagnostics are unavailable.

edges

Two-column integer edge matrix used when prepared is omitted. Supply either edges/edge.weights or adj.list/weight.list, not both. Raw graph inputs cannot be combined with a prepared object.

n

Finite positive integer vertex count. When supplied with a prepared object, it must match the stored graph size.

adj.list

Optional adjacency list used when prepared is omitted.

weight.list

Optional edge-weight list parallel to adj.list.

edge.weights

Optional positive edge weights parallel to edges.

dim

Target embedding dimension.

init

Starting layout used when coords is omitted. "classical_mds" (the default) uses classical.mds(). "metric_mds" uses stress-minimizing metric.mds() with its default native SGD backend. Both require an all-pairs prepared object. "weighted_grip" runs grip() with metric = "edge_length" on the graph edges first, and "random" uses centered Gaussian coordinates.

weighted.grip.args

Named list of additional tuning arguments passed to grip() when init = "weighted_grip". Graph inputs, dim, seed, and metric are supplied by edge.kk() and may not be repeated here.

stiffness.method, stiffness.transform, density.mix.schedule, bandwidth, density.n

Parameters passed to edge.length.density.stiffness().

distance.power, stiffness.floor, stiffness.ceiling

Additional stiffness constructor parameters.

scale.mode

Scale policy for edge targets. "profiled" analytically refits s at every state evaluation, "identity" fixes s = 1, "fixed_initial" fits s once at the first continuation stage, and "user" uses scale.

scale

User scale for scale.mode = "user".

max.iter

Maximum iterations per continuation stage.

initial.step, step.shrink, armijo.factor, grad.tol, min.step

Line-search controls.

edge.length.epsilon

Small stabilizer for fixed-path embedded lengths.

distance.floor

Positive floor for relative residuals.

recenter

If TRUE, recenter the layout after accepted steps.

return.trace

If TRUE, keep per-iteration trace rows and coordinate frames. If FALSE, omit those payloads while retaining compact stage summaries in metadata$stage_summaries.

diagnostics

If TRUE, attach the common GMDS diagnostic panel.

seed

Random seed used for init = "weighted_grip" and init = "random".

engine

Optimizer engine. "cpp" uses the Rcpp backend for the edge-stress loop; "R" uses the reference implementation.

Value

A "grip_gmds_layout" object with method "edge_kk".

Details

For scalable repair from an existing layout, pass coords or an edge-only object from prepare.edge.kk(). When raw graph inputs are supplied, edge.kk() uses edge-only preparation whenever coords are supplied or init is "weighted_grip" or "random". Use init = "weighted_grip" for a scalable weighted-GRIP warm start followed by edge-KK polish. If coords is omitted and either MDS initializer is requested, use an all-pairs prepared object from prepare.graph.geodesic.mds() or prepare.geodesic.kk() instead.

Examples

cycle_edges <- edges.cycle(6)
theta <- seq(0, 2 * pi, length.out = 7)[-7]
initial <- cbind(cos(theta), sin(theta))
prepared <- prepare.edge.kk(cycle_edges, n = 6)
fit <- edge.kk(
  coords = initial, prepared = prepared,
  max.iter = 1, density.n = 32, engine = "R"
)