% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/grip_layout.R
\name{grip}
\alias{grip}
\title{Compute a GRIP layout}
\usage{
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,
  disconnected = c("components", "error"),
  metric = c("hop", "edge_length"),
  metric_neighbor_cap = NULL,
  length_normalization = c("median", "mean", "none")
)
}
\arguments{
\item{edges}{Two-column integer matrix of edges (1-based vertex ids).}

\item{n}{Number of vertices.}

\item{adj_list}{Adjacency list (1-based) for undirected graphs.}

\item{weight_list}{Parallel list of edge lengths for \code{adj_list}.
The edge-length-metric engine requires it; in the hop-metric engine,
\code{NULL} treats all edges as length 1. All supplied lengths must be
finite and strictly positive.}

\item{edge_weights}{Vector of edge lengths for \code{edges}, in the same
order as its rows. The edge-length-metric engine requires it; in the
hop-metric engine, \code{NULL} treats all edges as length 1. All supplied
lengths must be finite and strictly positive. The selected engine
determines whether lengths also define graph distances.}

\item{dim}{Layout dimension (2 or 3). Default is 3.}

\item{placement}{Initial placement strategy. "circle" is only used for 2D.}

\item{preset}{Optional tuning preset. \code{NULL} uses the quality-first
defaults. \code{"carpet"} applies a preset tuned for
Sierpinski-carpet-like graphs and validated on carpet levels 3 and 4.
\code{"mesh"} applies a preset tuned for rectangular lattice graphs and
validated on 8x8 and 12x12 mesh layouts. \code{"torus"} applies a preset
tuned for 3D torus layouts and validated on torus sizes from 8x8 through
20x20. \code{"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.}

\item{rounds}{Initial rounds for refinement.}

\item{final_rounds}{Final rounds for refinement.}

\item{num_init}{Number of initial vertices in the coarsest level.}

\item{num_nbrs}{Maximum number of graph-distance neighbors retained for local
refinement at each filtration level.}

\item{r}{Main local temperature adaptation rate in \code{[0, 1]}.}

\item{s}{Non-negative boost factor applied when successive displacements have
a consistent direction.}

\item{repulsion_factor}{Non-negative multiplier applied to GRIP's
finest-level repulsive force scale.}

\item{coarse_repulsion_factor}{Non-negative multiplier applied to the extra
coarse-level active-set repulsion term. \code{0} disables that extra term.}

\item{coarse_repulsion_sample}{Positive integer sample size used to
approximate active-set-wide repulsion on larger coarse levels.}

\item{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.}

\item{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.}

\item{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.}

\item{final_mode}{Final full-graph refinement mode. \code{"fr"} keeps the
current Fruchterman-Reingold-style final stage. \code{"kk_repulse"} uses a
KK-style local distance-matching update with explicit active-set
repulsion instead of the final FR phase.}

\item{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 \code{K_mish} parameter.}

\item{insertion_anchor_scope}{Anchor-eligibility rule used during multiscale
insertion. \code{"any_higher"} matches the historical GRIP behavior and
allows anchors from any already placed higher MISF level.
\code{"prev_misf"} restricts anchors to the immediately previous MISF
level only.}

\item{insertion_anchor_strategy}{Anchor-selection rule used during
multiscale insertion. \code{"first"} keeps the historical
first-anchors-found BFS behavior. \code{"distance_band"} keeps exploring
until the \code{K_mish}-th anchor distance band is exhausted, then places
the new vertex from that less order-sensitive anchor pool.
\code{"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. \code{"spread_prev"} is a
symmetry-oriented band strategy intended to be paired with
\code{insertion_anchor_scope = "prev_misf"}; it selects anchors with broad
angular and geometric coverage before placement.}

\item{level0_insertion_mode}{Level-0 insertion placement override used only
when the finest filtration level is first populated. \code{"inherit"}
keeps the current GRIP behavior. \code{"barycenter"} disables the 2D
circle heuristic at level 0 and uses barycentric anchor placement.
\code{"least_squares"} uses a multi-anchor least-squares distance fit at
level 0 before any local micro-polish.}

\item{level0_anchor_count}{Positive integer number of already placed anchors
to collect for level-0 insertion experiments. By default this inherits
\code{insertion_anchor_count}. The legacy behavior uses 3.}

\item{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.}

\item{lgkk_polish_rounds}{Non-negative integer number of experimental
landmark-geodesic KK polish iterations applied after the main GRIP solve.
\code{0} disables the polish.}

\item{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 \code{NULL}.}

\item{lgkk_rounds_coarse}{Optional non-negative integer number of compiled
LGKK rounds applied on coarse MISF levels with \code{misf_level > 1}.
When \code{NULL}, this falls back to \code{lgkk_multiscale_rounds}.}

\item{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 (\code{misf_level == 1}). When \code{NULL}, this falls back to
\code{lgkk_multiscale_rounds}.}

\item{lgkk_rounds_final}{Optional non-negative integer number of compiled
LGKK rounds applied after the full graph level completes its standard GRIP
rounds (\code{misf_level == 0}). When \code{NULL}, this falls back to
\code{lgkk_multiscale_rounds}.}

\item{lgkk_local_nbrs}{Number of nearest graph-metric neighbors retained per
vertex in the LGKK sparse local set when either LGKK stage is enabled.}

\item{lgkk_landmark_count}{Number of farthest-point landmarks retained per
vertex in the LGKK sparse long-range set when either LGKK stage is
enabled.}

\item{lgkk_multiscale_scope}{Scope for the compiled multiscale LGKK stage.
\code{"all"} applies it after every eligible MISF level, including the
final full-graph level. \code{"coarse"} applies it only on coarse levels.}

\item{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.}

\item{tinit_factor}{Initial temperature factor.}

\item{seed}{Optional RNG seed for reproducibility. If NULL, uses current time.}

\item{disconnected}{How to handle disconnected graphs:
\code{"components"} (default) lays out each connected component separately
and packs them into one coordinate matrix; \code{"error"} stops with an
error.}

\item{metric}{Graph metric used by the multiscale GRIP engine.
\code{"hop"} (default) uses unweighted shortest-path hop counts to build
the MISF hierarchy and graph neighborhoods. \code{"edge_length"} uses
shortest-path distances obtained by summing the supplied positive edge
lengths. See \bold{Edge-length semantics} for the exact role of edge
lengths in each mode.}

\item{metric_neighbor_cap}{Weighted-metric search limit used only when
\code{metric = "edge_length"}. \code{NULL} performs the exact weighted
neighborhood search and stops once the required neighbors and anchors are
filled. A positive integer enables an approximate search by limiting the
number of settled vertices per search. It is an error to supply this
argument with \code{metric = "hop"}.}

\item{length_normalization}{Global normalization applied only when
\code{metric = "edge_length"}: \code{"median"} (default) divides every
edge length by their median, \code{"mean"} divides by their mean, and
\code{"none"} preserves the supplied numerical scale. It is an error to
supply this argument with \code{metric = "hop"}.}
}
\value{
A numeric matrix with `n` rows and `dim` columns.
}
\description{
This is the primary layout API. It uses the quality-first multiscale GRIP
engine with extra coarse-level global repulsion to reduce foldovers while
preserving the usual GRIP refinement structure. With \code{preset = NULL},
the default profile is tuned for higher-quality layouts and automatically
tapers \code{final_rounds} on larger graphs.
}
\details{
\strong{Edge-length semantics}

The arguments \code{edge_weights} and \code{weight_list} are historically
named but represent positive edge \emph{lengths} or traversal costs, not
connection strengths, capacities, or similarities. A larger value requests
a longer geometric edge. If the available values are strengths for which a
larger value means a closer connection, convert them to positive lengths
before calling \code{grip()}, for example with a scientifically appropriate
reciprocal or other monotone decreasing transformation.

With \code{metric = "hop"}, the standard GRIP hierarchy, insertion anchors,
and retained local neighborhoods use combinatorial shortest-path distance:
every traversed edge contributes one hop. When edge lengths are supplied,
they are nevertheless used as the desired lengths of adjacent vertex pairs
in the attractive force calculation. Thus this mode is useful when topology
should determine the multiscale organization but adjacent edges should have
unequal target lengths. No global length normalization is performed in this
mode. If no lengths are supplied, every edge has desired length one. Optional
LGKK stages use the supplied edge lengths for their geodesic distances even
though the standard GRIP stages remain hop based.

With \code{metric = "edge_length"}, positive edge lengths are required. The
same lengths determine desired adjacent-edge lengths and the shortest-path
metric used for the MISF hierarchy, insertion anchors, retained graph
neighborhoods, and LGKK stages. Dijkstra-style weighted shortest paths are
used instead of hop-count breadth-first searches. By default, all lengths
are divided by their median before layout; this preserves relative geometry
while placing the numerical scale near the solver's unit scale. Use
\code{length_normalization = "mean"} for mean scaling or \code{"none"} when
the absolute supplied scale is intentional. Multiplying all input lengths
by the same positive constant therefore leaves the default normalized solve
unchanged.

For \code{edges} input, provide one value per row through
\code{edge_weights}. For \code{adj_list} input, provide a parallel
\code{weight_list}: \code{weight_list[[i]][j]} is the length of the edge from
vertex \code{i} to \code{adj_list[[i]][j]}. For an undirected graph, the
adjacency and length entries should be symmetric.
}
\examples{
edges <- edges.mesh(4, 4)
coords <- grip(edges, n = max(edges), dim = 2,
                      coarse_repulsion_factor = 0.2,
                      coarse_repulsion_sample = 8,
                      coarse_repulsion_exact_below = 32,
                      seed = 1)
round(coords, 3)

# Use edge lengths throughout the multiscale graph metric.
path <- cbind(1:5, 2:6)
lengths <- c(1, 1, 2, 1, 1)
weighted.coords <- grip(
  path, n = 6, edge_weights = lengths,
  metric = "edge_length", dim = 2,
  rounds = 4, final_rounds = 4, num_init = 3, seed = 1
)
}
\references{
Gajer, P. and Kobourov, S.G. (2002). GRIP: Graph dRawing with Intelligent
Placement. \emph{Journal of Graph Algorithms and Applications}, 6(3),
203--224. doi:10.7155/jgaa.00052.

Gajer, P., Goodrich, M.T. and Kobourov, S.G. (2004). A multi-dimensional
approach to force-directed layouts of large graphs.
\emph{Computational Geometry}, 29(1), 3--18.
doi:10.1016/j.comgeo.2004.03.014.
}
