| Title: | Bayesian Analysis of Non-Stationary Gaussian Process Models |
|---|---|
| Description: | Enables off-the-shelf functionality for fully Bayesian, nonstationary Gaussian process modeling. The approach to nonstationary modeling involves a closed-form, convolution-based covariance function with spatially-varying parameters; these parameter processes can be specified either deterministically (using covariates or basis functions) or stochastically (using approximate Gaussian processes). Stationary Gaussian processes are a special case of our methodology, and we furthermore implement approximate Gaussian process inference to account for very large spatial data sets (Finley, et al (2017) <doi:10.48550/arXiv.1702.00434>). Bayesian inference is carried out using Markov chain Monte Carlo methods via the "nimble" package, and posterior prediction for the Gaussian process at unobserved locations is provided as a post-processing step. Also provided are nearest-neighbor Gaussian process components for use directly in user-written model code, where the spatial process is retained as a latent field: neighbor-structure construction, a latent-field density and matching simulation function, a purpose-built Metropolis-Hastings sampler that updates the field one node at a time, and posterior prediction at unobserved locations. |
| Authors: | Daniel Turek [aut, cre], Mark Risser [aut], Fabian Ketwaroo [aut] |
| Maintainer: | Daniel Turek <[email protected]> |
| License: | GPL-3 |
| Version: | 0.3.1 |
| Built: | 2026-10-11 15:26:36 UTC |
| Source: | https://github.com/cran/BayesNSGP |
calcQF calculates the quadratic form in the multivariate Gaussian
based on the NNGP approximation, for a specific parameter combination. The
quadratic form is t(u)C^{-1}v.
calcQF(u, v, AD, nID)calcQF(u, v, AD, nID)
u |
Vector; left product. |
v |
Vector; right product |
AD |
N x (k+1) matrix; the first k columns are the 'A' matrix, and the
last column is the 'D' vector. Represents the Cholesky of |
nID |
N x k matrix of neighbor indices. |
A list with two components: (1) an N x 2 array containing the same spatial coordinates, ordered by MMD, and (2) the same thing, but with any NA values removed.
calculateAD_ns calculates A and D matrices (the Cholesky of the
precision matrix) needed for the NNGP approximation.
calculateAD_ns( dist1_3d, dist2_3d, dist12_3d, Sigma11, Sigma22, Sigma12, log_sigma_vec, log_tau_vec, nID, N, k, nu, d )calculateAD_ns( dist1_3d, dist2_3d, dist12_3d, Sigma11, Sigma22, Sigma12, log_sigma_vec, log_tau_vec, nID, N, k, nu, d )
dist1_3d |
N x (k+1) x (k+1) array of distances in the x-coordinate direction. |
dist2_3d |
N x (k+1) x (k+1) array of distances in the y-coordinate direction. |
dist12_3d |
N x (k+1) x (k+1) array of cross-distances. |
Sigma11 |
N-vector; 1-1 element of the Sigma() process. |
Sigma22 |
N-vector; 2-2 element of the Sigma() process. |
Sigma12 |
N-vector; 1-2 element of the Sigma() process. |
log_sigma_vec |
N-vector; process standard deviation values. |
log_tau_vec |
N-vector; nugget standard deviation values. |
nID |
N x k matrix of neighbor indices. |
N |
Scalar; number of data measurements. |
k |
Scalar; number of nearest neighbors. |
nu |
Scalar; Matern smoothness parameter. |
d |
Scalar; dimension of the spatial domain. |
A N x (k+1) matrix; the first k columns are the 'A' matrix, and the last column is the 'D' vector.
calculateU_ns calculates the (sparse) matrix U (i.e., the Cholesky
of the inverse covariance matrix) using a nonstationary covariance function.
The output only contains non-zero values and is stored as three vectors:
(1) the row indices, (2) the column indices, and (3) the non-zero values.
NOTE: this code assumes the all inputs correspond to the ORDERED locations.
calculateU_ns( dist1_3d, dist2_3d, dist12_3d, Sigma11, Sigma22, Sigma12, log_sigma_vec, log_tau_vec, nu, nID, cond_on_y, N, k, d, M = 0 )calculateU_ns( dist1_3d, dist2_3d, dist12_3d, Sigma11, Sigma22, Sigma12, log_sigma_vec, log_tau_vec, nu, nID, cond_on_y, N, k, d, M = 0 )
dist1_3d |
N x (k+1) x (k+1) array of distances in the x-coordinate direction. |
dist2_3d |
N x (k+1) x (k+1) array of distances in the y-coordinate direction. |
dist12_3d |
N x (k+1) x (k+1) array of cross-distances. |
Sigma11 |
N-vector; 1-1 element of the Sigma() process. |
Sigma22 |
N-vector; 2-2 element of the Sigma() process. |
Sigma12 |
N-vector; 1-2 element of the Sigma() process. |
log_sigma_vec |
N-vector; process standard deviation values. |
log_tau_vec |
N-vector; nugget standard deviation values. |
nu |
Scalar; Matern smoothness parameter. |
nID |
N x k matrix of (ordered) neighbor indices. |
cond_on_y |
A matrix indicating whether the conditioning set for each
(ordered) location is on the latent process (y, |
N |
Scalar; number of data measurements. |
k |
Scalar; number of nearest neighbors. |
d |
Scalar; dimension of the spatial domain. |
M |
Scalar; number of prediction sites. |
Returns a sparse matrix representation of the Cholesky of the precision matrix for a fixed set of covariance parameters.
Computes the Nearest-Neighbor Gaussian Process (NNGP)
factorization components for each location:
the regression coefficients () and conditional variances ()
following the algorithms described by Finley et al. (2019)
computeAD(edist, nid.dist, neighbors.id, rho, sigma2, k)computeAD(edist, nid.dist, neighbors.id, rho, sigma2, k)
edist |
Numeric matrix ( |
nid.dist |
Numeric matrix ( |
neighbors.id |
Integer matrix ( |
rho |
Positive numeric scalar. Length-scale parameter |
sigma2 |
Positive numeric scalar. Marginal variance |
k |
Positive integer. Maximum number of neighbors. |
This function computes the parameters of the NNGP factorization by expressing the joint distribution as a product of conditional Gaussian densities:
where denotes the set of neighbors of location .
For each location , the conditional distribution is:
where:
is a vector of regression coefficients
is the conditional variance
These quantities are obtained from the covariance structure:
where:
is the covariance matrix among neighbors
is the covariance between location and its neighbors
The covariance structure is defined using an exponential covariance function.
These parameters are used to efficiently evaluate the NNGP likelihood and simulate from the process.
A numeric matrix () where:
First columns: regression coefficients ( matrix)
Last column: conditional variances ( diagonal entries)
Fabian Ketwaroo
Finley, A. O., Datta, A., Cook, B. D., Morton, D. C., Andersen, H. E., & Banerjee, S. (2019). Efficient algorithms for Bayesian nearest neighbor Gaussian processes. *Journal of Computational and Graphical Statistics*, 28(2), 401–414. doi:10.1080/10618600.2018.1537924
coords <- matrix(runif(40), ncol = 2) Nk = 5 res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk)coords <- matrix(runif(40), ncol = 2) Nk = 5 res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk)
Constructs the local covariance matrix associated with a focal location and its neighbor set under the Nearest-Neighbor Gaussian Process (NNGP).
computeC(fdist, ndist, rho, sigma2)computeC(fdist, ndist, rho, sigma2)
fdist |
Numeric matrix ( |
ndist |
Numeric vector (length |
rho |
Positive numeric scalar. Length-scale parameter |
sigma2 |
Positive numeric scalar. Marginal variance parameter |
This function constructs the local covariance matrix used in the NNGP approximation for conditional Gaussian distributions. The covariance structure is defined using an exponential covariance function.
The structure of the matrix is:
Top-left block: covariance among neighbors
Last row/column: covariance between focal location and neighbors
Bottom-right: marginal variance of the focal location
A small nugget term (1e-6) is added to the diagonal for numerical stability.
A numeric matrix of dimension representing the
local covariance matrix for the focal location and its neighbors.
Fabian Ketwaroo
Computes ordered neighbor sets based on Vecchia's approximation for a set of spatial coordinates. Locations are first ordered by their x-coordinate, and neighbors are selected from previously ordered locations.
computeNeighbors(coords, k, proj)computeNeighbors(coords, k, proj)
coords |
Numeric matrix ( |
k |
Positive integer. Number of neighbors for each location. |
proj |
Coordinate reference system (CRS) used to compute distances. Can be an EPSG code
(e.g., 4326) or a CRS object compatible with |
Neighbor selection follows a Vecchia-type ordering. For each location ,
neighbors are chosen from the set of previously ordered locations .
Distances are computed using sf::st_distance and depend on the CRS.
The first location has no neighbors. For the first locations, all previous
locations are used as neighbors. For subsequent locations, the nearest
neighbors among previously ordered points are selected.
A list with components:
Matrix of coordinates sorted by x-coordinate
Matrix () of pairwise distances between sorted coordinates
Binary matrix () indicating neighbor relationships
Matrix () of neighbor indices for each location
Matrix () of distances to neighbors
Fabian Ketwaroo
coords <- matrix(runif(40), ncol = 2) res <- computeNeighbors(coords, k = 5, proj = 4326)coords <- matrix(runif(40), ncol = 2) res <- computeNeighbors(coords, k = 5, proj = 4326)
Evaluates the quadratic form appearing in the Gaussian log-likelihood under the Nearest-Neighbor Gaussian Process (NNGP).
computeQF(u, v, AD, neighbors.id)computeQF(u, v, AD, neighbors.id)
u |
Numeric vector (length |
v |
Numeric vector (length |
AD |
Numeric matrix (
|
neighbors.id |
Integer matrix ( |
This function computes the quadratic form associated with the NNGP precision matrix without explicitly constructing the full covariance or precision matrix.
The expression is obtained by decomposing the joint Gaussian density into a product of conditional densities:
where denotes the set of neighbors of location .
Each term corresponds to a squared, standardized conditional residual:
and the quadratic form is:
This provides an efficient way to evaluate the Gaussian log-likelihood under the NNGP approximation.
A scalar value representing the quadratic form:
Fabian Ketwaroo
computeAD
conditionLatentObs assigns q_y(i) vs q_z(i) following Section 5.1
in Katzfuss and Guinness (2018). This function only needs to be run once
per SGV analysis.
conditionLatentObs(nID, coords_ord, N)conditionLatentObs(nID, coords_ord, N)
nID |
N x k matrix of neighbor indices. |
coords_ord |
N x 2 matrix of locations. |
N |
Scalar; number of locations (observed only!). |
A matrix indicating whether the conditioning set for each location
is on the latent process (y, 1) or the observed values (z, 0).
Cy_sm calculates the normalized sparse kernel for a fixed
set of bump function hyperparameters and returns the nonzero entries. Note
that the matrix is calculated and returned in dense format.
crossCy_sm( Xdists, coords, Pcoords, d, n1, n2, r0, s0, cstat_opt, normalize, bumpLocs, rads, ampls, shps, Xdist1_sq, Xdist2_sq, Xdist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, log_sigma_vec, Plog_sigma_vec )crossCy_sm( Xdists, coords, Pcoords, d, n1, n2, r0, s0, cstat_opt, normalize, bumpLocs, rads, ampls, shps, Xdist1_sq, Xdist2_sq, Xdist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, log_sigma_vec, Plog_sigma_vec )
Xdists |
N x N matrix of Euclidean distances |
coords |
N x d matrix of coordinate/input locations |
Pcoords |
N x d matrix of coordinate/input locations |
d |
Scalar; dimension of the spatial domain. |
n1 |
Scalar; number of outer products. |
n2 |
Scalar; number of bump functions in each outer product. |
r0 |
Scalar; length-scale of sparse stationary kernel. |
s0 |
Scalar; signal-variance of sparse stationary kernel. |
cstat_opt |
Scalar; determines the compactly supported kernel. See Details. |
normalize |
Logical; should C_sparse have 1's along the diagonal (1 = TRUE) |
bumpLocs |
Array of bump function locations (n2*d x n1) |
rads |
Matrix of bump function radii (n1 x n2; denoted |
ampls |
Matrix of bump function amplitudes (n1 x n2; denoted |
shps |
Matrix of bump function shape parameters (n1 x n2; denoted |
Xdist1_sq |
N x N matrix; contains values of pairwise squared distances in the x-coordinate. |
Xdist2_sq |
N x N matrix; contains values of pairwise squared distances in the y-coordinate. |
Xdist12 |
N x N matrix; contains values of pairwise signed cross-
distances between the x- and y-coordinates. The sign of each element is
important; see |
Sigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each station. |
Sigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each station. |
Sigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each station. |
PSigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each station. |
PSigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each station. |
PSigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each station. |
nu |
Scalar; Matern smoothness parameter. |
log_sigma_vec |
Vector of length N; log of the signal standard deviation. |
Plog_sigma_vec |
Vector of length N; log of the signal standard deviation. |
Returns a sparse matrix (N x 3) of the nonzero elements of the product between the core and sparse kernel.
Cy_sm calculates the normalized sparse kernel for a fixed
set of bump function hyperparameters and returns the nonzero entries. Note
that the matrix is calculated and returned in dense format.
Cy_sm( dists, coords, N, d, n1, n2, r0, s0, cstat_opt, normalize, bumpLocs, rads, ampls, shps, dist1_sq, dist2_sq, dist12, Sigma11, Sigma22, Sigma12, nu, log_sigma_vec, lognuggetSD )Cy_sm( dists, coords, N, d, n1, n2, r0, s0, cstat_opt, normalize, bumpLocs, rads, ampls, shps, dist1_sq, dist2_sq, dist12, Sigma11, Sigma22, Sigma12, nu, log_sigma_vec, lognuggetSD )
dists |
N x N matrix of Euclidean distances |
coords |
N x d matrix of coordinate/input locations |
N |
Scalar; number of data measurements. |
d |
Scalar; dimension of the spatial domain. |
n1 |
Scalar; number of outer products. |
n2 |
Scalar; number of bump functions in each outer product. |
r0 |
Scalar; length-scale of sparse stationary kernel. |
s0 |
Scalar; signal-variance of sparse stationary kernel. |
cstat_opt |
Scalar; determines the compactly supported kernel. See Details. |
normalize |
Logical; should C_sparse have 1's along the diagonal |
bumpLocs |
Array of bump function locations (n2*d x n1) |
rads |
Matrix of bump function radii (n1 x n2; denoted |
ampls |
Matrix of bump function amplitudes (n1 x n2; denoted |
shps |
Matrix of bump function shape parameters (n1 x n2; denoted |
dist1_sq |
N x N matrix; contains values of pairwise squared distances in the x-coordinate. |
dist2_sq |
N x N matrix; contains values of pairwise squared distances in the y-coordinate. |
dist12 |
N x N matrix; contains values of pairwise signed cross-
distances between the x- and y-coordinates. The sign of each element is
important; see |
Sigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each station. |
Sigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each station. |
Sigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each station. |
nu |
Scalar; Matern smoothness parameter. |
log_sigma_vec |
Vector of length N; log of the signal standard deviation. |
lognuggetSD |
Vector of length N; log of the error standard deviation. |
Returns a sparse matrix (N x 3) of the nonzero elements of the product between the core and sparse kernel.
determineNeighbors returns an N x k matrix of the nearest neighbors
for spatial locations coords, with the ith row giving indices of the k nearest
neighbors to the ith location, which are selected from among the 1,...(i-1)
other spatial locations. The first row is -1's, since the first location has
no neighbors. The i=2 through i=(k+1) rows each necessarily contain 1:i.
determineNeighbors(coords, k)determineNeighbors(coords, k)
coords |
N x 2 array of N 2-dimensional (x,y) spatial coordinates. |
k |
Scalar; number of neighbors |
An N x k matrix of nearest neighbor indices
coords <- cbind(runif(100), runif(100)) determineNeighbors(coords, 20)coords <- cbind(runif(100), runif(100)) determineNeighbors(coords, 20)
Visualizes the neighbor set for a given location based on an ordered Nearest-Neighbor Gaussian Process (NNGP) constructed using Vecchia's approximation.
displayNeighbors(ind, coords.sorted, neighbor_idx, proj)displayNeighbors(ind, coords.sorted, neighbor_idx, proj)
ind |
Integer index of the focal location (in the sorted order). |
coords.sorted |
Numeric matrix ( |
neighbor_idx |
Integer matrix ( |
proj |
Coordinate reference system (CRS) used for plotting. Can be an EPSG code
or a CRS object compatible with |
The function assumes that coordinates and neighbor indices are based on an ordered representation of the data (e.g., sorted by x-coordinate or another ordering used in Vecchia's approximation).
The neighbor set for location consists of previously ordered locations,
as defined by the NNGP construction.
A ggplot2 object showing:
All spatial locations (black markers)
The focal location (red point)
Its neighbors (blue points)
A vertical reference line at the focal location's x-coordinate
Fabian Ketwaroo
computeNeighbors
coords <- matrix(runif(40), ncol = 2) res <- computeNeighbors(coords, k = 5, proj = 4326) p <- displayNeighbors( ind = 10, coords.sorted = res$coords_sorted, neighbor_idx = res$neighbor_idx, proj = 4326 ) print(p)coords <- matrix(runif(40), ncol = 2) res <- computeNeighbors(coords, k = 5, proj = 4326) p <- displayNeighbors( ind = 10, coords.sorted = res$coords_sorted, neighbor_idx = res$neighbor_idx, proj = 4326 ) print(p)
dmnorm_gp2Scale (and rmnorm_gp2Scale) calculate the usual Gaussian
likelihood for a fixed set of parameters (but with sparse matrices). Finally,
the distributions must be registered within nimble.
dmnorm_gp2Scale(x, mean, Cov, N, Nnz, log = 1)dmnorm_gp2Scale(x, mean, Cov, N, Nnz, log = 1)
x |
Vector of measurements |
mean |
Vector of mean values |
Cov |
Matrix of size N x N; sparse kernel |
N |
Number of measurements in x |
Nnz |
Number of measurements in x |
log |
Logical; should the density be evaluated on the log scale. |
Returns the Gaussian likelihood using the gp2Scale sparse covariance.
Evaluates the log-density of a multivariate normal distribution under the Nearest-Neighbor Gaussian Process (NNGP) approximation as defined by Data et al 2016.
dmnorm_NN_GP(x, mu, AD, neighbors.id, log = 1)dmnorm_NN_GP(x, mu, AD, neighbors.id, log = 1)
x |
Numeric vector (length |
mu |
Numeric vector (length |
AD |
Numeric matrix (
|
neighbors.id |
Integer matrix ( |
log |
Logical/Integer. If |
The NNGP approximation factorizes the joint density as:
leading to the log-density:
where:
are conditional variances
is the quadratic form computed by computeQF
The quadratic form corresponds to:
This formulation avoids constructing the sparse covariance matrix, enabling scalable likelihood evaluation for large spatial datasets.
A scalar value corresponding to the (log-)density.
Fabian Ketwaroo
Datta, A., Banerjee, S., Finley, A.O. and Gelfand, A.E., 2016. Hierarchical nearest-neighbor Gaussian process models for large geostatistical datasets. *Journal of the American Statistical Association*, 111(514), 800-812. doi:10.1080/01621459.2015.1044091
M <- 2000 # number of spatial locations coords <- matrix(runif(2*M), ncol = 2) Nk <- 15 # number of neighbors res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk) w <- rmnorm_NN_GP(n = 1, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk]) loglike <- dmnorm_NN_GP(w, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk], log = TRUE)M <- 2000 # number of spatial locations coords <- matrix(runif(2*M), ncol = 2) Nk <- 15 # number of neighbors res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk) w <- rmnorm_NN_GP(n = 1, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk]) loglike <- dmnorm_NN_GP(w, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk], log = TRUE)
dmnorm_nngp (and rmnorm_nngp) calculate the approximate NNGP
likelihood for a fixed set of parameters (i.e., A and D matrices). Finally,
the distributions must be registered within nimble.
dmnorm_nngp(x, mean, AD, nID, N, k, log)dmnorm_nngp(x, mean, AD, nID, N, k, log)
x |
N-vector of data. |
mean |
N-vector with current values of the mean |
AD |
N x (k+1) matrix; the first k columns are the 'A' matrix, and the last column is the 'D' vector. |
nID |
N x k matrix of neighbor indices. |
N |
Scalar; number of data measurements. |
k |
Scalar; number of nearest neighbors. |
log |
Scalar; should the density be on the log scale (1) or not (0). |
The NNGP approximate density.
dmnorm_sgv (and rmnorm_sgv) calculate the approximate SGV
likelihood for a fixed set of parameters (i.e., the U matrix). Finally,
the distributions must be registered within nimble.
dmnorm_sgv(x, mean, U, N, k, log = 1)dmnorm_sgv(x, mean, U, N, k, log = 1)
x |
Vector of measurements |
mean |
Vector of mean valiues |
U |
Matrix of size N x 3; representation of a sparse N x N Cholesky of the precision matrix. The first two columns contain row and column indices, respectively, and the last column is the nonzero elements of the matrix. |
N |
Number of measurements in x |
k |
Number of neighbors for the SGV approximation. |
log |
Logical; should the density be evaluated on the log scale. |
Returns the SGV approximation to the Gaussian likelihood.
Computes the exponential covariance matrix.
expcov(edists, rho, sigma2)expcov(edists, rho, sigma2)
edists |
Numeric matrix ( |
rho |
Positive numeric scalar. Length-scale parameter |
sigma2 |
Positive numeric scalar. Signal variance parameter |
The covariance function is defined as:
where is the distance between locations and .
Larger values of imply slower decay of correlation with distance
(i.e., stronger spatial autocorrelation). Larger values of
increase the marginal variance of the process.
A small nugget term (1e-6) is added to the diagonal for numerical stability.
A numeric matrix () representing the covariance between spatial locations.
Fabian Ketwaroo
coords <- matrix(runif(10), ncol = 2) d <- as.matrix(dist(coords)) expcov(edists = d, rho = 0.5, sigma2 = 1)coords <- matrix(runif(10), ncol = 2) d <- as.matrix(dist(coords)) expcov(edists = d, rho = 0.5, sigma2 = 1)
Identifies all "children" (reverse neighbors) for a specific target location
in a Nearest-Neighbor Gaussian Process (NNGP). It searches the neighbor matrix
to find all locations that condition upon location .
get_single_reverse_neighbors(target_node, neighbor_idx)get_single_reverse_neighbors(target_node, neighbor_idx)
target_node |
Integer. The index of the location |
neighbor_idx |
Integer matrix ( |
This function optimizes the reverse lookup for a single node by avoiding the
full list construction loop. It uses vectorization to scan rows of
the neighbor matrix where the row index is greater than the target index
, enforcing the Directed Acyclic Graph (DAG) structure of the NNGP.
An integer vector containing the indices of all locations
that have target_node as a neighbor, maintaining the NNGP
ordering constraint ().
Fabian Ketwaroo
nn_matrix <- matrix(c(0, 0, 1, 0, 1, 2, 1, 3), nrow = 4, byrow = TRUE) # Find which nodes have node 1 as a neighbor get_single_reverse_neighbors(target_node = 1, neighbor_idx = nn_matrix)nn_matrix <- matrix(c(0, 0, 1, 0, 1, 2, 1, 3), nrow = 4, byrow = TRUE) # Find which nodes have node 1 as a neighbor get_single_reverse_neighbors(target_node = 1, neighbor_idx = nn_matrix)
inverseEigen calculates the inverse eigendecomposition – in other
words, the covariance elements based on the eigenvalues and vectors. For a
2x2 anisotropy (covariance) matrix, we parameterize the three unique values
in terms of the two log eigenvalues and a rotation parameter on the
rescaled logit. The function is coded as a nimbleFunction (see the
nimble package) but can also be used as a regular R function.
inverseEigen(eigen_comp1, eigen_comp2, eigen_comp3, which_Sigma)inverseEigen(eigen_comp1, eigen_comp2, eigen_comp3, which_Sigma)
eigen_comp1 |
N-vector; contains values of the log of the first anisotropy eigenvalue for a set of locations. |
eigen_comp2 |
N-vector; contains values of the log of the second anisotropy eigenvalue for a set of locations. |
eigen_comp3 |
N-vector; contains values of the rescaled logit of the anisotropy rotation for a set of locations. |
which_Sigma |
Scalar; one of |
A vector of anisotropy values (Sigma11, Sigma22, or Sigma12; depends
on which_Sigma) for the corresponding set of locations.
# Generate some eigendecomposition elements (all three are real-valued) eigen_comp1 <- rnorm(10) eigen_comp2 <- rnorm(10) eigen_comp3 <- rnorm(10) inverseEigen( eigen_comp1, eigen_comp2, eigen_comp3, 2) # Return the Sigma22 values# Generate some eigendecomposition elements (all three are real-valued) eigen_comp1 <- rnorm(10) eigen_comp2 <- rnorm(10) eigen_comp3 <- rnorm(10) inverseEigen( eigen_comp1, eigen_comp2, eigen_comp3, 2) # Return the Sigma22 values
matern_corr calculates a stationary Matern correlation matrix for a
fixed set of locations, based on a range and smoothness parameter. This
function is primarily used for the "npGP" and "approxGP" models. The
function is coded as a nimbleFunction (see the nimble package)
but can also be used as a regular R function.
matern_corr(dist, rho, nu)matern_corr(dist, rho, nu)
dist |
N x N matrix; contains values of pairwise Euclidean distances in the x-y plane. |
rho |
Scalar; "range" parameter used to rescale distances |
nu |
Scalar; Matern smoothness parameter. |
A correlation matrix for a fixed set of stations and fixed parameter values.
# Generate some coordinates coords <- cbind(runif(100),runif(100)) nu <- 2 # Calculate distances -- can use nsDist to calculate Euclidean distances dist_list <- nsDist(coords, isotropic = TRUE) # Calculate the correlation matrix corMat <- matern_corr(sqrt(dist_list$dist1_sq), 1, nu)# Generate some coordinates coords <- cbind(runif(100),runif(100)) nu <- 2 # Calculate distances -- can use nsDist to calculate Euclidean distances dist_list <- nsDist(coords, isotropic = TRUE) # Calculate the correlation matrix corMat <- matern_corr(sqrt(dist_list$dist1_sq), 1, nu)
nimble_sparse_chol
nimble_sparse_chol(i, j, x, n)nimble_sparse_chol(i, j, x, n)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
n |
Length of the vector |
nimble_sparse_chol
nimble_sparse_cholesky(i, j, x)nimble_sparse_cholesky(i, j, x)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
nimble_sparse_crossprod
nimble_sparse_crossprod(i, j, x, z, n, subset, transp)nimble_sparse_crossprod(i, j, x, z, n, subset, transp)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
n |
Length of the vector |
subset |
Optional vector of rows to include in the calculation. |
transp |
Optional indicator of using the transpose |
nimble_sparse_solve
nimble_sparse_solve(i, j, x, z)nimble_sparse_solve(i, j, x, z)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
nimble_sparse_crossprod
nimble_sparse_solveMat(i, j, x, z, transp)nimble_sparse_solveMat(i, j, x, z, transp)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
transp |
Optional indicator of using the transpose |
nimble_sparse_tcrossprod
nimble_sparse_tcrossprod(i, j, x, subset)nimble_sparse_tcrossprod(i, j, x, subset)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
subset |
Optional vector of rows to include in the calculation. |
Generates a posterior predictive draw at a new location using the
Nearest-Neighbor Gaussian Process (NNGP) approximation. This function
automatically handles coordinate sorting, neighbor selection, and distance
calculations internally following Algorithm 2 of Finley et al. (2019).
NNGP.pred(x0, coords_sorted, rho, sigma2, w.x0.all, k)NNGP.pred(x0, coords_sorted, rho, sigma2, w.x0.all, k)
x0 |
Numeric matrix ( |
coords_sorted |
Numeric matrix ( |
rho |
Positive numeric scalar. Length-scale parameter |
sigma2 |
Positive numeric scalar. Marginal variance parameter |
w.x0.all |
Numeric vector of length |
k |
Integer. The number of nearest neighbors to consider for the prediction approximation. |
The function merges the prediction point into the training
coordinates and identifies the nearest neighbors from the set of
points that precede it in the x-axis ordering.
The predictive distribution is Gaussian:
where is the **Kriging mean** and is the **Kriging variance**
defined as:
Here:
is the set of indices of the nearest neighbors of among the observed locations.
is the vector of realizations of the spatial process at those neighbor locations (passed as w.s.x0).
is the covariance vector between and its neighbors in .
is the covariance matrix among the neighbors in .
The exponential covariance function is used: .
A small nugget () is added to the diagonal of for
numerical stability.
The internal subsetting of w.x0.all ensures that
correctly represents the process realizations at the identified neighbor locations.
A numeric scalar representing a posterior predictive draw at location .
Fabian Ketwaroo
Finley, A. O., Datta, A., Cook, B. D., Morton, D. C., Andersen, H. E., & Banerjee, S. (2019). Efficient algorithms for Bayesian nearest neighbor Gaussian processes. *Journal of Computational and Graphical Statistics*, 28(2), 401–414. doi:10.1080/10618600.2018.1537924
# Setup training data M <- 50 coords <- matrix(runif(M * 2), ncol = 2) w_all <- rnorm(M) # Mock spatial realizations # coords_sorted and w.x0.all must be aligned to the same x-sorted order # that computeNeighbors() would produce, since NNGP.pred() selects # neighbors by position in that order. ord <- order(coords[, 1]) coords_sorted <- coords[ord, ] w_sorted <- w_all[ord] # Predict at a new location using k = 5 neighbors new_loc <- c(0.5, 0.5) pred_draw <- NNGP.pred(x0 = new_loc, coords_sorted = coords_sorted, rho = 0.2, sigma2 = 1.0, w.x0.all = w_sorted, k = 5)# Setup training data M <- 50 coords <- matrix(runif(M * 2), ncol = 2) w_all <- rnorm(M) # Mock spatial realizations # coords_sorted and w.x0.all must be aligned to the same x-sorted order # that computeNeighbors() would produce, since NNGP.pred() selects # neighbors by position in that order. ord <- order(coords[, 1]) coords_sorted <- coords[ord, ] w_sorted <- w_all[ord] # Predict at a new location using k = 5 neighbors new_loc <- c(0.5, 0.5) pred_draw <- NNGP.pred(x0 = new_loc, coords_sorted = coords_sorted, rho = 0.2, sigma2 = 1.0, w.x0.all = w_sorted, k = 5)
nsCorr calculates a nonstationary correlation matrix for a
fixed set of locations, based on vectors of the unique anisotropy
parameters for each station. Since the correlation function uses a
spatially-varying Mahalanobis distance, this function requires coordinate-
specific distance matrices (see below). The function is coded as a
nimbleFunction (see the nimble package) but can also be
used as a regular R function.
nsCorr(dist1_sq, dist2_sq, dist12, Sigma11, Sigma22, Sigma12, nu, d)nsCorr(dist1_sq, dist2_sq, dist12, Sigma11, Sigma22, Sigma12, nu, d)
dist1_sq |
N x N matrix; contains values of pairwise squared distances in the x-coordinate. |
dist2_sq |
N x N matrix; contains values of pairwise squared distances in the y-coordinate. |
dist12 |
N x N matrix; contains values of pairwise signed cross-
distances between the x- and y-coordinates. The sign of each element is
important; see |
Sigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each station. |
Sigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each station. |
Sigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each station. |
nu |
Scalar; Matern smoothness parameter. |
d |
Scalar; dimension of the spatial coordinates. |
A correlation matrix for a fixed set of stations and fixed parameter values.
# Generate some coordinates and parameters coords <- cbind(runif(100),runif(100)) Sigma11 <- rep(1, 100) # Identity anisotropy process Sigma22 <- rep(1, 100) Sigma12 <- rep(0, 100) nu <- 2 # Calculate distances dist_list <- nsDist(coords) # Calculate the correlation matrix corMat <- nsCorr(dist_list$dist1_sq, dist_list$dist2_sq, dist_list$dist12, Sigma11, Sigma22, Sigma12, nu, ncol(coords))# Generate some coordinates and parameters coords <- cbind(runif(100),runif(100)) Sigma11 <- rep(1, 100) # Identity anisotropy process Sigma22 <- rep(1, 100) Sigma12 <- rep(0, 100) nu <- 2 # Calculate distances dist_list <- nsDist(coords) # Calculate the correlation matrix corMat <- nsCorr(dist_list$dist1_sq, dist_list$dist2_sq, dist_list$dist12, Sigma11, Sigma22, Sigma12, nu, ncol(coords))
nsCrosscorr calculates a nonstationary cross-correlation matrix
between two fixed sets of locations (a prediction set with M locations, and
the observed set with N locations), based on vectors of the unique anisotropy
parameters for each station. Since the correlation function uses a
spatially-varying Mahalanobis distance, this function requires coordinate-
specific distance matrices (see below). The function is coded as a
nimbleFunction (see the nimble package) but can also be
used as a regular R function.
nsCrosscorr( Xdist1_sq, Xdist2_sq, Xdist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, d )nsCrosscorr( Xdist1_sq, Xdist2_sq, Xdist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, d )
Xdist1_sq |
M x N matrix; contains values of pairwise squared cross-distances in the x-coordinate. |
Xdist2_sq |
M x N matrix; contains values of pairwise squared cross-distances in the y-coordinate. |
Xdist12 |
M x N matrix; contains values of pairwise signed cross/cross-
distances between the x- and y-coordinates. The sign of each element is
important; see |
Sigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each observed location. |
Sigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each observed location. |
Sigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each observed location. |
PSigma11 |
Vector of length N; contains the 1-1 element of the anisotropy process for each prediction location. |
PSigma22 |
Vector of length N; contains the 2-2 element of the anisotropy process for each prediction location. |
PSigma12 |
Vector of length N; contains the 1-2 element of the anisotropy process for each prediction location. |
nu |
Scalar; Matern smoothness parameter. |
d |
Scalar; dimension of the spatial domain. |
A M x N cross-correlation matrix for two fixed sets of stations and fixed parameter values.
# Generate some coordinates and parameters coords <- cbind(runif(100),runif(100)) Sigma11 <- rep(1, 100) # Identity anisotropy process Sigma22 <- rep(1, 100) Sigma12 <- rep(0, 100) Pcoords <- cbind(runif(200),runif(200)) PSigma11 <- rep(1, 200) # Identity anisotropy process PSigma22 <- rep(1, 200) PSigma12 <- rep(0, 200) nu <- 2 # Calculate distances Xdist_list <- nsCrossdist(coords, Pcoords) # Calculate the correlation matrix XcorMat <- nsCrosscorr(Xdist_list$dist1_sq, Xdist_list$dist2_sq, Xdist_list$dist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, ncol(coords))# Generate some coordinates and parameters coords <- cbind(runif(100),runif(100)) Sigma11 <- rep(1, 100) # Identity anisotropy process Sigma22 <- rep(1, 100) Sigma12 <- rep(0, 100) Pcoords <- cbind(runif(200),runif(200)) PSigma11 <- rep(1, 200) # Identity anisotropy process PSigma22 <- rep(1, 200) PSigma12 <- rep(0, 200) nu <- 2 # Calculate distances Xdist_list <- nsCrossdist(coords, Pcoords) # Calculate the correlation matrix XcorMat <- nsCrosscorr(Xdist_list$dist1_sq, Xdist_list$dist2_sq, Xdist_list$dist12, Sigma11, Sigma22, Sigma12, PSigma11, PSigma22, PSigma12, nu, ncol(coords))
nsCrossdist calculates coordinate-specific cross distances in x, y,
and x-y for use in the nonstationary cross-correlation calculation. This
function is useful for calculating posterior predictions.
nsCrossdist(coords, Pcoords, scale_factor = NULL, isotropic = FALSE)nsCrossdist(coords, Pcoords, scale_factor = NULL, isotropic = FALSE)
coords |
N x 2 matrix; contains x-y coordinates of station (observed) locations. |
Pcoords |
M x 2 matrix; contains x-y coordinates of prediction locations. |
scale_factor |
Scalar; optional argument for re-scaling the distances. |
isotropic |
Logical; indicates whether distances should be calculated
using Euclidean distance ( |
A list of distances matrices, with the following components:
dist1_sq |
M x N matrix; contains values of pairwise squared cross- distances in the x-coordinate. |
dist2_sq |
M x N matrix; contains values of pairwise squared cross- distances in the y-coordinate. |
dist12 |
M x N matrix; contains values of pairwise signed cross- distances between the x- and y-coordinates. |
scale_factor |
Value of the scale factor used to rescale distances. |
# Generate some coordinates coords <- cbind(runif(100),runif(100)) Pcoords <- cbind(runif(200),runif(200)) # Calculate distances Xdist_list <- nsCrossdist(coords, Pcoords)# Generate some coordinates coords <- cbind(runif(100),runif(100)) Pcoords <- cbind(runif(200),runif(200)) # Calculate distances Xdist_list <- nsCrossdist(coords, Pcoords)
nsCrossdist3d generates and returns new 3-dimensional arrays containing
the former dist1_sq, dist2_s1, and dist12 matrices, but
only as needed for the k nearest-neighbors of each location.
these 3D matrices (dist1_3d, dist2_3d, and dist12_3d)
are used in the new implementation of calculateAD_ns().
nsCrossdist3d( coords, predCoords, P_nID, scale_factor = NULL, isotropic = FALSE )nsCrossdist3d( coords, predCoords, P_nID, scale_factor = NULL, isotropic = FALSE )
coords |
N x d matrix; contains the x-y coordinates of stations. |
predCoords |
M x d matrix |
P_nID |
N x k matrix; contains indices of nearest neighbors. |
scale_factor |
Scalar; optional argument for re-scaling the distances. |
isotropic |
Logical; indicates whether distances should be calculated
separately for each coordinate dimension (FALSE) or simultaneously for all
coordinate dimensions (TRUE). |
Arrays with nearest neighbor distances in each coordinate direction. When the spatial dimension d > 2, dist1_3d contains squared Euclidean distances, and dist2_3d and dist12_3d are empty.
# Generate some coordinates and neighbors coords <- cbind(runif(100),runif(100)) predCoords <- cbind(runif(200),runif(200)) P_nID <- FNN::get.knnx(coords, predCoords, k = 10)$nn.index # Prediction NN # Calculate distances Pdist <- nsCrossdist3d(coords, predCoords, P_nID)# Generate some coordinates and neighbors coords <- cbind(runif(100),runif(100)) predCoords <- cbind(runif(200),runif(200)) P_nID <- FNN::get.knnx(coords, predCoords, k = 10)$nn.index # Prediction NN # Calculate distances Pdist <- nsCrossdist3d(coords, predCoords, P_nID)
nsDist calculates x, y, and x-y distances for use in the
nonstationary correlation calculation. The sign of the cross-distance
is important. The function contains an optional argument for re-scaling
the distances such that the coordinates lie in a square.
nsDist(coords, scale_factor = NULL, isotropic = FALSE)nsDist(coords, scale_factor = NULL, isotropic = FALSE)
coords |
N x 2 matrix; contains the x-y coordinates of stations |
scale_factor |
Scalar; optional argument for re-scaling the distances. |
isotropic |
Logical; indicates whether distances should be calculated
separately for each coordinate dimension (FALSE) or simultaneously for all
coordinate dimensions (TRUE). |
A list of distances matrices, with the following components:
dist1_sq |
N x N matrix; contains values of pairwise squared distances in the x-coordinate. |
dist2_sq |
N x N matrix; contains values of pairwise squared distances in the y-coordinate. |
dist12 |
N x N matrix; contains values of pairwise signed cross- distances between the x- and y-coordinates. |
scale_factor |
Value of the scale factor used to rescale distances. |
# Generate some coordinates coords <- cbind(runif(100),runif(100)) # Calculate distances dist_list <- nsDist(coords) # Use nsDist to calculate Euclidean distances dist_Euclidean <- sqrt(nsDist(coords, isotropic = TRUE)$dist1_sq)# Generate some coordinates coords <- cbind(runif(100),runif(100)) # Calculate distances dist_list <- nsDist(coords) # Use nsDist to calculate Euclidean distances dist_Euclidean <- sqrt(nsDist(coords, isotropic = TRUE)$dist1_sq)
nsDist3d generates and returns new 3-dimensional arrays containing
the former dist1_sq, dist2_sq, and dist12 matrices, but
only as needed for the k nearest-neighbors of each location.
these 3D matrices (dist1_3d, dist2_3d, and dist12_3d)
are used in the new implementation of calculateAD_ns().
nsDist3d(coords, nID, scale_factor = NULL, isotropic = FALSE)nsDist3d(coords, nID, scale_factor = NULL, isotropic = FALSE)
coords |
N x 2 matrix; contains the x-y coordinates of stations. |
nID |
N x k matrix; contains indices of nearest neighbors. |
scale_factor |
Scalar; optional argument for re-scaling the distances. |
isotropic |
Logical; indicates whether distances should be calculated
separately for each coordinate dimension (FALSE) or simultaneously for all
coordinate dimensions (TRUE). |
Arrays with nearest neighbor distances in each coordinate direction.
# Generate some coordinates and neighbors coords <- cbind(runif(100),runif(100)) nID <- determineNeighbors(coords, 10) # Calculate distances nsDist3d(coords, nID)# Generate some coordinates and neighbors coords <- cbind(runif(100),runif(100)) nID <- determineNeighbors(coords, 10) # Calculate distances nsDist3d(coords, nID)
This function sets up and compiles a nimble model for a general nonstationary Gaussian process.
nsgpModel( tau_model = "constant", sigma_model = "constant", Sigma_model = "constant", sparse_model = "none", mu_model = "constant", likelihood = "fullGP", coords, data, constants = list(), monitorAllSampledNodes = TRUE, ... )nsgpModel( tau_model = "constant", sigma_model = "constant", Sigma_model = "constant", sparse_model = "none", mu_model = "constant", likelihood = "fullGP", coords, data, constants = list(), monitorAllSampledNodes = TRUE, ... )
tau_model |
Character; specifies the model to be used for the log(tau)
process. Options are |
sigma_model |
Character; specifies the model to be used for the
log(sigma) process. See |
Sigma_model |
Character; specifies the model to be used for the
Sigma anisotropy process. Options are |
sparse_model |
Character; specifies the model to be used for the sparse
kernel when using the gp2Scale likelihood. Defaults to |
mu_model |
Character; specifies the model to be used for the mu mean
process. Options are |
likelihood |
Character; specifies the likelihood model. Options are
|
coords |
N x d matrix of spatial coordinates. |
data |
N-vector; observed vector of the spatial process of interest |
constants |
A list of constants required to build the model; depends on the specific parameter process models chosen. |
monitorAllSampledNodes |
Logical; indicates whether all sampled nodes
should be stored ( |
... |
Additional arguments can be passed to the function; for example,
as an alternative to the |
A nimbleCode object.
# Generate some data: stationary/isotropic N <- 100 coords <- matrix(runif(2*N), ncol = 2) alpha_vec <- rep(log(sqrt(1)), N) # Log process SD delta_vec <- rep(log(sqrt(0.05)), N) # Log nugget SD Sigma11_vec <- rep(0.4, N) # Kernel matrix element 1,1 Sigma22_vec <- rep(0.4, N) # Kernel matrix element 2,2 Sigma12_vec <- rep(0, N) # Kernel matrix element 1,2 mu_vec <- rep(0, N) # Mean nu <- 0.5 # Smoothness dist_list <- nsDist(coords) Cor_mat <- nsCorr( dist1_sq = dist_list$dist1_sq, dist2_sq = dist_list$dist2_sq, dist12 = dist_list$dist12, Sigma11 = Sigma11_vec, Sigma22 = Sigma22_vec, Sigma12 = Sigma12_vec, nu = nu ) Cov_mat <- diag(exp(alpha_vec)) %*% Cor_mat %*% diag(exp(alpha_vec)) D_mat <- diag(exp(delta_vec)^2) set.seed(110) data <- as.numeric(mu_vec + t(chol(Cov_mat + D_mat)) %*% rnorm(N)) # Set up constants constants <- list( nu = 0.5, Sigma_HP1 = 2 ) # Defaults: tau_model = "constant", sigma_model = "constant", mu_model = "constant", # and Sigma_model = "constant" Rmodel <- nsgpModel(likelihood = "fullGP", constants = constants, coords = coords, data = data )# Generate some data: stationary/isotropic N <- 100 coords <- matrix(runif(2*N), ncol = 2) alpha_vec <- rep(log(sqrt(1)), N) # Log process SD delta_vec <- rep(log(sqrt(0.05)), N) # Log nugget SD Sigma11_vec <- rep(0.4, N) # Kernel matrix element 1,1 Sigma22_vec <- rep(0.4, N) # Kernel matrix element 2,2 Sigma12_vec <- rep(0, N) # Kernel matrix element 1,2 mu_vec <- rep(0, N) # Mean nu <- 0.5 # Smoothness dist_list <- nsDist(coords) Cor_mat <- nsCorr( dist1_sq = dist_list$dist1_sq, dist2_sq = dist_list$dist2_sq, dist12 = dist_list$dist12, Sigma11 = Sigma11_vec, Sigma22 = Sigma22_vec, Sigma12 = Sigma12_vec, nu = nu ) Cov_mat <- diag(exp(alpha_vec)) %*% Cor_mat %*% diag(exp(alpha_vec)) D_mat <- diag(exp(delta_vec)^2) set.seed(110) data <- as.numeric(mu_vec + t(chol(Cov_mat + D_mat)) %*% rnorm(N)) # Set up constants constants <- list( nu = 0.5, Sigma_HP1 = 2 ) # Defaults: tau_model = "constant", sigma_model = "constant", mu_model = "constant", # and Sigma_model = "constant" Rmodel <- nsgpModel(likelihood = "fullGP", constants = constants, coords = coords, data = data )
nsgpPredict conducts posterior prediction for MCMC samples generated
using nimble and nsgpModel.
nsgpPredict( model, samples, coords.predict, predict.process = TRUE, constants = list(), seed = 0, ... )nsgpPredict( model, samples, coords.predict, predict.process = TRUE, constants = list(), seed = 0, ... )
model |
A NSGP nimble object; the output of |
samples |
A matrix of |
coords.predict |
M x d matrix of prediction coordinates. |
predict.process |
Logical; determines whether the prediction corresponds to
the y(·) process ( |
constants |
An optional list of contants to use for prediction; alternatively, additional arguments can be passed to the function via the ... argument. |
seed |
An optional random seed argument for reproducibility. |
... |
Additional arguments can be passed to the function; for example,
as an alternative to the |
The output of the function is a list with two elements: obs,
a matrix of J posterior predictive samples for the N observed
locations (only for likelihood = "SGV", which produces predictions
for the observed locations by default; this element is NULL
otherwise); and pred, a corresponding matrix of posterior predictive
samples for the prediction locations. Ordering and neighbor selection
for the prediction coordinates in the SGV likelihood are conducted
internally, as with nsgpModel.
## Not run: # Generate some data: stationary/isotropic N <- 100 coords <- matrix(runif(2*N), ncol = 2) alpha_vec <- rep(log(sqrt(1)), N) # Log process SD delta_vec <- rep(log(sqrt(0.05)), N) # Log nugget SD Sigma11_vec <- rep(0.4, N) # Kernel matrix element 1,1 Sigma22_vec <- rep(0.4, N) # Kernel matrix element 2,2 Sigma12_vec <- rep(0, N) # Kernel matrix element 1,2 mu_vec <- rep(0, N) # Mean nu <- 0.5 # Smoothness dist_list <- nsDist(coords) Cor_mat <- nsCorr( dist1_sq = dist_list$dist1_sq, dist2_sq = dist_list$dist2_sq, dist12 = dist_list$dist12, Sigma11 = Sigma11_vec, Sigma22 = Sigma22_vec, Sigma12 = Sigma12_vec, nu = nu ) Cov_mat <- diag(exp(alpha_vec)) %*% Cor_mat %*% diag(exp(alpha_vec)) D_mat <- diag(exp(delta_vec)^2) set.seed(110) data <- as.numeric(mu_vec + t(chol(Cov_mat + D_mat)) %*% rnorm(N)) # Set up constants constants <- list( nu = 0.5, Sigma_HP1 = 2 ) # Defaults: tau_model = "constant", sigma_model = "constant", mu_model = "constant", # and Sigma_model = "constant" Rmodel <- nsgpModel(likelihood = "fullGP", constants = constants, coords = coords, data = data ) conf <- configureMCMC(Rmodel) Rmcmc <- buildMCMC(conf) Cmodel <- compileNimble(Rmodel) Cmcmc <- compileNimble(Rmcmc, project = Rmodel) samples <- runMCMC(Cmcmc, niter = 200, nburnin = 100) # Prediction predCoords <- as.matrix(expand.grid(seq(0,1,l=10),seq(0,1,l=10))) postpred <- nsgpPredict( model = Rmodel, samples = samples, coords.predict = predCoords ) ## End(Not run)## Not run: # Generate some data: stationary/isotropic N <- 100 coords <- matrix(runif(2*N), ncol = 2) alpha_vec <- rep(log(sqrt(1)), N) # Log process SD delta_vec <- rep(log(sqrt(0.05)), N) # Log nugget SD Sigma11_vec <- rep(0.4, N) # Kernel matrix element 1,1 Sigma22_vec <- rep(0.4, N) # Kernel matrix element 2,2 Sigma12_vec <- rep(0, N) # Kernel matrix element 1,2 mu_vec <- rep(0, N) # Mean nu <- 0.5 # Smoothness dist_list <- nsDist(coords) Cor_mat <- nsCorr( dist1_sq = dist_list$dist1_sq, dist2_sq = dist_list$dist2_sq, dist12 = dist_list$dist12, Sigma11 = Sigma11_vec, Sigma22 = Sigma22_vec, Sigma12 = Sigma12_vec, nu = nu ) Cov_mat <- diag(exp(alpha_vec)) %*% Cor_mat %*% diag(exp(alpha_vec)) D_mat <- diag(exp(delta_vec)^2) set.seed(110) data <- as.numeric(mu_vec + t(chol(Cov_mat + D_mat)) %*% rnorm(N)) # Set up constants constants <- list( nu = 0.5, Sigma_HP1 = 2 ) # Defaults: tau_model = "constant", sigma_model = "constant", mu_model = "constant", # and Sigma_model = "constant" Rmodel <- nsgpModel(likelihood = "fullGP", constants = constants, coords = coords, data = data ) conf <- configureMCMC(Rmodel) Rmcmc <- buildMCMC(conf) Cmodel <- compileNimble(Rmodel) Cmcmc <- compileNimble(Rmcmc, project = Rmodel) samples <- runMCMC(Cmcmc, niter = 200, nburnin = 100) # Prediction predCoords <- as.matrix(expand.grid(seq(0,1,l=10),seq(0,1,l=10))) postpred <- nsgpPredict( model = Rmodel, samples = samples, coords.predict = predCoords ) ## End(Not run)
orderCoordinatesMMD orders an array of (x,y) spatial coordinates
according to the "maximum minimum distance" (MMD), as described in Guinness,
2018. (Points are selected to maximize their minimum distance to already-
selected points).
orderCoordinatesMMD(coords, exact = FALSE)orderCoordinatesMMD(coords, exact = FALSE)
coords |
N x 2 array of N 2-dimensional (x,y) spatial coordinates. |
exact |
Logical; |
A list of distances matrices, with the following components:
orderedCoords |
N x 2 matrix; contains the ordered spatial coordinates
as |
orderedIndicesNoNA |
N-vector; contains the ordered indices with any NA values removed. |
coords <- cbind(runif(100), runif(100)) orderCoordinatesMMD(coords)coords <- cbind(runif(100), runif(100)) orderCoordinatesMMD(coords)
R_sparse_chol
R_sparse_chol(i, j, x, n)R_sparse_chol(i, j, x, n)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
n |
Length of the vector |
R_sparse_chol
R_sparse_cholesky(i, j, x)R_sparse_cholesky(i, j, x)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
nimble_sparse_crossprod
R_sparse_crossprod(i, j, x, z, n, subset = -1, transp = 1)R_sparse_crossprod(i, j, x, z, n, subset = -1, transp = 1)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
n |
Length of the vector |
subset |
Optional vector of rows to include in the calculation. |
transp |
Optional indicator of using the transpose |
nimble_sparse_solve
R_sparse_solve(i, j, x, z)R_sparse_solve(i, j, x, z)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
nimble_sparse_crossprod
R_sparse_solveMat(i, j, x, z, transp = 1)R_sparse_solveMat(i, j, x, z, transp = 1)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
z |
Vector to calculate the cross-product with. |
transp |
Optional indicator of using the transpose |
nimble_sparse_tcrossprod
R_sparse_tcrossprod(i, j, x, subset = -1)R_sparse_tcrossprod(i, j, x, subset = -1)
i |
Vector of row indices. |
j |
Vector of column indices. |
x |
Vector of values in the matrix. |
subset |
Optional vector of rows to include in the calculation. |
dmnorm_gp2Scale (and rmnorm_gp2Scale) calculate the usual Gaussian
likelihood for a fixed set of parameters (but with sparse matrices). Finally,
the distributions must be registered within nimble.
rmnorm_gp2Scale(n, mean, Cov, N, Nnz)rmnorm_gp2Scale(n, mean, Cov, N, Nnz)
n |
Number of realizations to generate |
mean |
Vector of mean values |
Cov |
Matrix of size N x N; sparse kernel |
N |
Number of measurements in x |
Nnz |
Number of measurements in x |
Not applicable.
Efficiently simulates a realization from a Gaussian process using the Nearest-Neighbor Gaussian Process (NNGP) approximation as described by Datta (2022).
rmnorm_NN_GP(n, mu, AD, neighbors.id)rmnorm_NN_GP(n, mu, AD, neighbors.id)
n |
Integer. Number of samples to generate. Currently only supports |
mu |
Numeric vector (length |
AD |
Numeric matrix (
|
neighbors.id |
Integer matrix ( |
The simulation follows the recursive form derived from the sparse Cholesky
factorization of the precision matrix (). Let
be the zero-mean spatial residuals. The NNGP simulates these residuals sequentially:
where:
is the neighbor set of location , such that .
are the kriging weights computed from the local covariance.
are independent innovations.
This sequential approach exploits the sparsity of the Cholesky factor ,
where and allows for
simulation, which is significantly faster than the standard
Cholesky decomposition for large .
A numeric vector (length ) representing a simulated realization
from the NNGP.
Fabian Ketwaroo
Datta, A. (2022). Nearest-neighbor sparse Cholesky matrices in spatial statistics. *Wiley Interdisciplinary Reviews: Computational Statistics*, 14(5), e1574. doi:10.1002/wics.1574
M <- 2000 # number of spatial locations coords <- matrix(runif(2*M), ncol = 2) Nk <- 15 # number of neighbors res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk) w <- rmnorm_NN_GP(n = 1, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk])M <- 2000 # number of spatial locations coords <- matrix(runif(2*M), ncol = 2) Nk <- 15 # number of neighbors res <- computeNeighbors(coords, k = Nk) AD <- computeAD(edist = res$edist_sorted, nid.dist = res$neighbors_dist, neighbors.id = res$neighbor_idx, rho = 0.1, sigma2 = 0.3, k = Nk) w <- rmnorm_NN_GP(n = 1, mu = rep(0, M), AD = AD[1:M, 1:(Nk+1)], neighbors.id = res$neighbor_idx[1:M, 1:Nk])
dmnorm_nngp (and rmnorm_nngp) calculate the approximate NNGP
likelihood for a fixed set of parameters (i.e., A and D matrices). Finally,
the distributions must be registered within nimble.
rmnorm_nngp(n, mean, AD, nID, N, k)rmnorm_nngp(n, mean, AD, nID, N, k)
n |
N-vector of data. |
mean |
N-vector with current values of the mean |
AD |
N x (k+1) matrix; the first k columns are the 'A' matrix, and the last column is the 'D' vector. |
nID |
N x k matrix of neighbor indices. |
N |
Scalar; number of data measurements. |
k |
Scalar; number of nearest neighbors. |
The NNGP approximate density.
dmnorm_sgv (and rmnorm_sgv) calculate the approximate SGV
likelihood for a fixed set of parameters (i.e., the U matrix). Finally,
the distributions must be registered within nimble.
rmnorm_sgv(n, mean, U, N, k)rmnorm_sgv(n, mean, U, N, k)
n |
Vector of measurements |
mean |
Vector of mean valiues |
U |
Matrix of size N x 3; representation of a sparse N x N Cholesky of the precision matrix. The first two columns contain row and column indices, respectively, and the last column is the nonzero elements of the matrix. |
N |
Number of measurements in x |
k |
Number of neighbors for the SGV approximation. |
Not applicable.
Pre-calculates the local graph structure, target indices, and specific
coordinate strings within the AD matrix for a single target node.
This forms the control list payload needed by sampler_RW_NN_GP.
RWNNGP_setup(node_id, AD, neighbors.id, Rneighbors.id, N.neighbors, k = k)RWNNGP_setup(node_id, AD, neighbors.id, Rneighbors.id, N.neighbors, k = k)
node_id |
Integer. The index of the specific spatial location currently
being set up for targeted random-walk sampling (ranges from 1 to |
AD |
Character. The name of the matrix containing the NNGP coefficients
within the NIMBLE model object (typically passed as a string like |
neighbors.id |
Integer matrix ( |
Rneighbors.id |
Integer vector. The reverse neighbor indices (children)
for |
N.neighbors |
Integer vector. A vector of length |
k |
Integer. The maximum number of neighbors specified in the NNGP configuration. |
This utility is designed to run in an R loop when configuring an MCMC specification
prior to model compilation. By converting matrix indexing operations into explicit
character node paths (e.g., "AD[5,1]"), it shifts the burden of matrix searching
from the runtime execution loop of the C++ compiled sampler into a one-time R setup cost.
It maps out how a change in node_id will ripple through its forward neighbors
and back through the reverse neighbors whose conditional distributions depend directly
on the target node's value.
A named list containing specific structural elements for the target node:
update_id: Integer vector combining the node_id and its reverse neighbors.
Fneighbors.id: Integer vector containing non-zero forward neighbor indices.
AFnodes: Character vector of parsed string addresses pointing to forward coefficients.
ARnodes: Character vector of parsed string addresses pointing to reverse coefficients.
A.neighbors: Flattened character vector of matrix addresses representing all relevant
neighborhood coefficients needed to re-evaluate residuals during the loop.
Fabian Ketwaroo
A custom NIMBLE sampler for updating individual spatial random effects under a Nearest-Neighbor Gaussian Process (NNGP) approximation. This sampler uses a factorized likelihood approach to perform highly efficient local Metropolis-Hastings sampling with a normal proposal distribution (Metropolis, 1953), implementing the adaptation routine given in Shaby and Wells (2011).
sampler_RW_NN_GP(model, mvSaved, target, control)sampler_RW_NN_GP(model, mvSaved, target, control)
model |
(uncompiled) model on which the MCMC is to be run |
mvSaved |
|
target |
The node to be sampled (a single spatial random effect scalar). |
control |
A list of control parameters:
|
Instead of calculating the full NNGP log-likelihood, which is
(where is the total number of spatial locations), this sampler exploits
the Directed Acyclic Graph (DAG) structure of the NNGP to reduce the complexity
of a single-node update to , where is the number of neighbors.
During the MCMC configuration stage, the sampler automatically queries the local
graph architecture using get_single_reverse_neighbors and RWNNGP_setup
to resolve dependencies internally. When a single node is updated,
only its own conditional density and the conditional densities of its "children"
(the reverse neighbors that depend on it) are affected.
The local log-Metropolis-Hastings ratio () is calculated as:
where:
and are the current and proposed conditional residuals for the target node.
is the set of reverse neighbors (indices such that ).
and are the current and proposed residuals for those reverse neighbors.
represents the conditional variances.
The residuals are updated efficiently using the difference ,
such that , where is the NNGP
regression coefficient.
Fabian Ketwaroo
Metropolis, N., Rosenbluth, A. W., Rosenbluth, M. N., Teller, A. H., and Teller, E. (1953). Equation of state calculations by fast computing machines. *The Journal of Chemical Physics*, 21(6), 1087-1092.
Shaby, B. A. and Wells, M. T. (2011). Exploring an adaptive Metropolis-Hastings algorithm. *Department of Statistical Science, Cornell University Tech Report*.
sgvSetup is a wrapper function that sets up the SGV approximation.
Three objects are required: (1) ordering the locations, (2) identify nearest
neighbors, and (3) determine the conditioning set. This function only needs
to be run once per SGV analysis.
sgvSetup( coords, coords_pred = NULL, k = 15, seed = NULL, pred.seed = NULL, order_coords = TRUE, order_coords_pred = TRUE )sgvSetup( coords, coords_pred = NULL, k = 15, seed = NULL, pred.seed = NULL, order_coords = TRUE, order_coords_pred = TRUE )
coords |
Matrix of observed locations. |
coords_pred |
Optional matrix of prediction locations. |
k |
Number of neighbors. |
seed |
Setting the seed for reproducibility of the observed location ordering |
pred.seed |
Setting the seed for reproducibility of the prediction ordering. |
order_coords |
Logical; should the coordinates be ordered. |
order_coords_pred |
Logical; should the coordinates be ordered. |
A list with the following components:
ord |
A vector of ordering position for the observed locations. |
ord_pred |
A vector of ordering position for the prediction
locations (if |
ord_all |
A concatenated vector of |
coords_ord |
A matrix of ordered locations (observed and prediction), included for convenience. |
nID_ord |
A matrix of (ordered) neighbor indices. |
condition_on_y_ord |
A matrix indicating whether the conditioning
set for each (ordered) location is on the latent process (y, |