Skip to contents

Manifold-agnostic search for a data-centered base point: numerically minimizes the total geodesic distance sum(dist(X, p)) from a candidate point p to every row of X, via multi-start optim (L-BFGS-B, falling back to Nelder-Mead if it errors). The manifold enters only through dist and through the search space, which is described by init, in_domain, lower, upper and project. See optimize_base_point_torus for the torus case.

Usage

optimize_base_point(
  X,
  dist,
  init,
  in_domain = function(p) TRUE,
  lower = -Inf,
  upper = Inf,
  project = identity,
  n_start = 10,
  maxit = 200,
  seed = 42
)

Arguments

X

A matrix or data frame of manifold data; rows are samples, columns are coordinates.

dist

Function f(X, p) returning the vector of geodesic distances between each row of X and p (see new_manifold).

init

Function f(n) returning a matrix whose n rows are the restart points. It is called with the random seed set to seed, without altering the global random number generator.

in_domain

Function f(p) returning TRUE if p is an admissible candidate; the objective is Inf otherwise. Defaults to accepting every p.

lower, upper

Bounds on p passed to optim for L-BFGS-B. Default to -Inf and Inf (unconstrained).

project

Function f(p) applied to the best point found, e.g. to map it back onto the manifold. Defaults to identity.

n_start

Number of random restarts used to avoid local minima of the (non-convex) objective. Defaults to 10.

maxit

Maximum number of optim iterations per restart. Defaults to 200.

seed

Integer random seed used to generate the restart points, for reproducibility. Defaults to 42.

Value

A list with three elements: p (the best point found across all restarts, after project), value (its total distance to the rows of X), and convergence (the optim convergence code of the best restart; 0 indicates successful convergence).

Examples

X <- matrix(runif(20), nrow = 10, ncol = 2)
optimize_base_point(X, dist = dist_torus,
                    init = function(n) matrix(runif(2 * n), ncol = 2),
                    lower = c(0, 0), upper = c(1, 1), n_start = 5)
#> $p
#> [1] 0.5607423 0.6844678
#> 
#> $value
#> [1] 2.675805
#> 
#> $convergence
#> [1] 0
#>