Optimize a kernel Gram-gKK layout
Source:R/export_examples.R, R/gmds_kernel_gram_gkk.R
kernel.gram.gkk.Rdkernel.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,
initis used.- prepared
Optional object returned by
prepare.edge.kk(),prepare.graph.geodesic.mds()orprepare.geodesic.kk(). Edge-only objects fromprepare.edge.kk()report only edge diagnostics; all-pairs GMDS path and chord diagnostics are unavailable.- edges
Two-column integer edge matrix used when
preparedis 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
preparedis 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
starwhenstaris omitted.- star
Optional object from
graph.riemannian.star.structure().- dim
Target embedding dimension.
- init
Starting layout used when
coordsis 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()whenstaris omitted.- star.quantile
Optional quantile filter passed to
graph.riemannian.star.structure()whenstaris 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 refitssat every state evaluation,"identity"fixess = 1,"fixed_initial"fitssonce at the first continuation stage, and"user"usesscale.- 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.
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"
)