Applies a graph-Laplacian spatial smoother to a hyperSpec::hyperSpec object whose spectra are laid out on a regular width x height image grid. For each wavelength band the smoothed image is the solution of

graphSmooth(
  x,
  width,
  height,
  alpha = 1,
  neighbors = 4L,
  backend = c("rust", "r"),
  solver = c("cg", "bicgstab")
)

# S4 method for class 'hyperSpec'
graphSmooth(
  x,
  width,
  height,
  alpha = 1,
  neighbors = 4L,
  backend = c("rust", "r"),
  solver = c("cg", "bicgstab")
)

Arguments

x

a hyperSpec::hyperSpec object whose spc slot has nrow(x) == width * height.

width, height

integer image dimensions.

alpha

non-negative numeric smoothing strength. Larger values produce smoother output; alpha = 0 returns x unchanged.

neighbors

integer, either 4 (von Neumann) or 8 (Moore) neighborhood connectivity.

backend

one of "r" or "rust"; selects the solver implementation.

solver

iterative Krylov method used by the Rust backend, either "cg" (Conjugate Gradient, the default; I + alpha L is symmetric positive-definite) or "bicgstab" (BiCGSTAB, for the general case). Ignored by the R backend, which uses a direct Matrix::solve().

Value

A hyperSpec::hyperSpec object with the same metadata as x whose spc slot has been replaced by the smoothed spectra.

Details

$$(I + \alpha L)\, x = b,$$

where L = D - W is the combinatorial Laplacian of the pixel adjacency graph (4- or 8-connectivity) and b is the original band.

Two backends are available:

  • backend = "rust" (default): the high-performance Rust kernel (graph_smooth_rust()). The pixel neighborhood graph is rebuilt in Rust with petgraph from width/height/neighbors (no adjacency matrix crosses the FFI boundary), the Laplacian L = D - W is assembled in sparse (CSC) form, and each band is solved with an iterative Krylov method (solver: CG or BiCGSTAB). Requires the package's Rust extension to be compiled. Silently falls back to "r" if unavailable or fails.

  • backend = "r": the pure-R baseline (graph_smooth_r()) built on Matrix sparse routines. Here the Laplacian is assembled as a dgCMatrix and solved with Matrix::solve(). Used as the correctness reference and the pure-R side of the benchmark.