Skip to contents

kernel.gram.gkk() extends edge-only gKK with a local Riemannian star penalty. The off-diagonal Gram term preserves target inner products between pairs of incident edge directions: $$ \frac{\lambda_{\mathrm{gram}}}{2}\sum_{u}\sum_{v<v'\in N(u)} \omega_u(v,v')\left( \langle z_v-z_u,z_{v'}-z_u\rangle - s^2 w_{uv}w_{uv'}\cos\alpha_u(v,v')\right)^2. $$ The star weights are built by graph.riemannian.star.structure(), usually with an antipodal kernel controlled by angle.power.

Usage

kernel.gram.gkk(
  coords = NULL,
  prepared = NULL,
  edges = NULL,
  n = NULL,
  adj_list = NULL,
  weight_list = NULL,
  edge_weights = NULL,
  X = NULL,
  star = NULL,
  dim = 2L,
  init = c("classical_mds", "metric_mds", "random"),
  angle.power = 4,
  reliability = c("length.balance", "none"),
  min.angle.weight = 0,
  star.quantile = 0,
  lambda.edge = 1,
  lambda.gram = 1,
  stiffness_method = c("density", "uniform", "distance_power"),
  stiffness_transform = c("identity", "sqrt", "log"),
  density_mix = 1,
  bandwidth = NULL,
  density_n = 512L,
  distance_power = 0,
  stiffness_floor = 0,
  stiffness_ceiling = Inf,
  scale_mode = c("profiled", "identity", "user"),
  scale = NULL,
  max_iter = 50L,
  initial_step = 0.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.

X

Optional ambient/source coordinates used to build star when star is omitted.

star

Optional object from graph.riemannian.star.structure().

dim

Target embedding dimension.

init

Starting layout used when coords is omitted. "classical_mds" uses classical scaling (the default), "metric_mds" uses stress MDS through smacof, both from an all-pairs prepared object; "random" uses centered Gaussian coordinates.

angle.power, reliability, min.angle.weight

Passed to graph.riemannian.star.structure() when star is omitted.

star.quantile

Optional quantile filter passed to graph.riemannian.star.structure() when star is omitted.

lambda.edge, lambda.gram

Non-negative weights for the diagonal edge-length and off-diagonal Gram penalties.

stiffness_method, stiffness_transform, density_mix, bandwidth, density_n

Parameters passed to edge.length.density.stiffness() to construct edge-length stiffnesses for the diagonal edge term.

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.

diagnostics

If TRUE, attach the common GMDS diagnostic panel.

seed

Random seed used only for 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 "kernel_gram_gkk".

Examples

cycle_edges <- edges.cycle(6)
theta <- seq(0, 2 * pi, length.out = 7)[-7]
initial <- cbind(cos(theta), sin(theta))
prepared <- prepare.graph.geodesic.mds(cycle_edges, n = 6)
fit <- kernel.gram.gkk(
  coords = initial, prepared = prepared, X = initial,
  max_iter = 1, density_n = 32, engine = "R"
)