% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mrts_sphere.R
\name{mrts_sphere}
\alias{mrts_sphere}
\title{Multi-resolution thin-plate spline basis on the sphere}
\usage{
mrts_sphere(knot, k, X)
}
\arguments{
\item{knot}{Numeric matrix with two columns giving knot locations as
\verb{(latitude, longitude)} in degrees.}

\item{k}{Integer. Number of basis functions to construct (the rank of
the basis). Must satisfy \verb{2 <= k <= nrow(knot)}.}

\item{X}{Numeric matrix with two columns giving prediction locations
as \verb{(latitude, longitude)} in degrees, where the basis is evaluated.}
}
\value{
A list with one element:
\describe{
\item{\code{mrts}}{An \verb{nrow(X) x k} numeric matrix whose columns are the
basis functions evaluated at the rows of \code{X}.}
}
}
\description{
Builds a set of \code{k} multi-resolution thin-plate spline (MRTS) basis
functions on the sphere from a set of knot locations, and evaluates
them at the prediction locations \code{X}.
}
\details{
The first basis function is constant (\code{sqrt(1/n)}); the remaining
\code{k - 1} basis functions are obtained from the eigen-decomposition of
the centered knot kernel matrix, following the construction described
in the reference.
}
\examples{
## Build a small global grid in (lat, lon) degrees.
n_lon <- 12
n_lat <- 8
lon_seq <- seq(-180, 150, length.out = n_lon)
lat_seq <- seq( -80,  80, length.out = n_lat)
grid <- as.matrix(expand.grid(lat = lat_seq, lon = lon_seq))

## Pick 30 knots and evaluate the MRTS basis at every grid point.
set.seed(1)
knots <- grid[sample(nrow(grid), 30), ]
res <- mrts_sphere(knots, k = 5, X = grid)
dim(res$mrts)   # nrow(grid) x k

## Recovering a simulated spherical exponential field with the basis.
if (requireNamespace("fields", quietly = TRUE)) {
  # Great-circle distance (km) -> exponential covariance.
  d_grid    <- fields::rdist.earth(grid[, 2:1], miles = FALSE)
  cov_field <- exp(-d_grid / 2000)
  y_true    <- as.numeric(t(chol(cov_field + diag(1e-8, nrow(grid)))) \%*\%
                          rnorm(nrow(grid)))

  # Noisy observations at the knot locations.
  obs_idx <- match(data.frame(t(knots)), data.frame(t(grid)))
  z_obs   <- y_true[obs_idx] + rnorm(nrow(knots), sd = 0.3)

  # Project into the MRTS basis (least squares) and predict on the grid.
  B_obs    <- res$mrts[obs_idx, , drop = FALSE]
  beta_hat <- qr.solve(B_obs, z_obs)
  y_hat    <- res$mrts \%*\% beta_hat
  sqrt(mean((y_hat - y_true)^2))   # RMSE
}

}
\references{
Multi-resolution approximations of Gaussian processes for large
spatial datasets on the sphere. \emph{Environmetrics}, 2025.
\doi{10.1002/env.70092}
}
