From 7c7b6733e1adfbd9fc2f3b5708ab531b3f193bde Mon Sep 17 00:00:00 2001 From: Till Hoffmann Date: Wed, 11 Dec 2024 19:31:43 -0500 Subject: [PATCH] Support different length scales for different dimensions in graph GPs (ported from onnela-lab/gptools#23). --- DESCRIPTION | 2 +- NEWS.md | 5 + R/model.R | 22 +- inst/extdata/gptools/fft1.stan | 7 +- inst/extdata/gptools/fft2.stan | 7 +- inst/extdata/gptools/graph.stan | 367 +++++++++++++++++++++++++++++++- 6 files changed, 395 insertions(+), 15 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f330abf..ba3e332 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: gptoolsStan Title: Gaussian Processes on Graphs and Lattices in 'Stan' -Version: 0.1.0 +Version: 0.2.0 Authors@R: c( person("Till", "Hoffmann", , "thoffmann@hsph.harvard.edu", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-4403-0722")), diff --git a/NEWS.md b/NEWS.md index 38b9c41..2f9cae4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ # gptoolsStan 0.1.0 Initial release. + +# gptoolsStan 0.2.0 + +- Graph-based approximations of Gaussian processes now support different length scales along different dimensions (ported from https://github.com/onnela-lab/gptools/pull/23). This change requires cmdstan 2.36.0 or above due to a bug in `gp_matern32_cov` (see https://github.com/stan-dev/math/pull/3084). +- Functions ending `_log_abs_det_jacobian` have been renamed to `_log_abs_det_jac` to comply with upcoming changes (see https://github.com/stan-dev/stanc3/issues/1470 for details). diff --git a/R/model.R b/R/model.R index 113eb4e..a27d187 100644 --- a/R/model.R +++ b/R/model.R @@ -9,10 +9,26 @@ #' #' # Compile the model with paths set up to include 'Stan' sources from 'gptoolsStan'. #' model <- cmdstan_model( -#' stan_file="/path/to/your/model.stan", -#' include_paths=gptools_include_path(), +#' stan_file = "/path/to/your/model.stan", +#' include_paths = gptools_include_path(), #' ) #' } gptools_include_path <- function() { - system.file("extdata", package="gptoolsStan") + version <- package_version(cmdstanr::cmdstan_version()) + if (version < package_version("2.36.0")) { + warning( + sprintf( + paste( + "cmdstan<2.36.0 had a bug in the evaluation of Matern 3/2 kernels", + "with different length scales for different dimensions; see", + "https://github.com/stan-dev/math/pull/3084 for details. Your", + "model may yield unexpected results or crash if you use", + "nearest-neighbor Gaussian processes with Matern 3/2 kernels.", + "Your cmdstan version is %s; consider upgrading." + ), + version + ) + ) + } + system.file("extdata", package = "gptoolsStan") } diff --git a/inst/extdata/gptools/fft1.stan b/inst/extdata/gptools/fft1.stan index 66710ab..c1435b3 100644 --- a/inst/extdata/gptools/fft1.stan +++ b/inst/extdata/gptools/fft1.stan @@ -75,11 +75,14 @@ Evaluate the log absolute determinant of the Jacobian associated with :param n: Size of the real signal. Necessary because the size cannot be inferred from :code:`rfft`. :returns: Log absolute determinant of the Jacobian. */ -real gp_rfft_log_abs_det_jacobian(vector cov_rfft, int n) { +real gp_rfft_log_abs_det_jac(vector cov_rfft, int n) { vector[n %/% 2 + 1] rfft_scale = gp_evaluate_rfft_scale(cov_rfft, n); return - sum(log(rfft_scale[1:n %/% 2 + 1])) -sum(log(rfft_scale[2:(n + 1) %/% 2])) - log(2) * ((n - 1) %/% 2) + n * log(n) / 2; } +real gp_rfft_log_abs_det_jacobian(vector cov_rfft, int n) { + reject("`gp_rfft_log_abs_det_jacobian` has been renamed to `gp_rfft_log_abs_det_jac` to comply with upcoming changes (see https://github.com/stan-dev/stanc3/issues/1470 for details)."); +} /** @@ -94,7 +97,7 @@ real gp_rfft_lpdf(vector y, vector loc, vector cov_rfft) { int n = size(y); int nrfft = n %/% 2 + 1; vector[n] z = gp_rfft(y, loc, cov_rfft); - return std_normal_lpdf(z) + gp_rfft_log_abs_det_jacobian(cov_rfft, n); + return std_normal_lpdf(z) + gp_rfft_log_abs_det_jac(cov_rfft, n); } diff --git a/inst/extdata/gptools/fft2.stan b/inst/extdata/gptools/fft2.stan index 9b810fc..5c02d18 100644 --- a/inst/extdata/gptools/fft2.stan +++ b/inst/extdata/gptools/fft2.stan @@ -140,7 +140,7 @@ Evaluate the log absolute determinant of the Jacobian associated with Fourier transform :code:`cov_rfft2`). :returns: Log absolute determinant of the Jacobian. */ -real gp_rfft2_log_abs_det_jacobian(matrix cov_rfft2, int width) { +real gp_rfft2_log_abs_det_jac(matrix cov_rfft2, int width) { int height = rows(cov_rfft2); int n = width * height; int fftwidth = width %/% 2 + 1; @@ -171,6 +171,9 @@ real gp_rfft2_log_abs_det_jacobian(matrix cov_rfft2, int width) { ladj += - log2() * nterms + n * log(n) / 2; return ladj; } +real gp_rfft2_log_abs_det_jacobian(matrix cov_rfft2, int width) { + reject("`gp_rfft2_log_abs_det_jacobian` has been renamed to `gp_rfft2_log_abs_det_jac` to comply with upcoming changes (see https://github.com/stan-dev/stanc3/issues/1470 for details)."); +} /** @@ -185,7 +188,7 @@ Evaluate the log probability of a two-dimensional Gaussian process realization i */ real gp_rfft2_lpdf(matrix y, matrix loc, matrix cov_rfft2) { return std_normal_lpdf(to_vector(gp_rfft2(y, loc, cov_rfft2))) - + gp_rfft2_log_abs_det_jacobian(cov_rfft2, cols(y)); + + gp_rfft2_log_abs_det_jac(cov_rfft2, cols(y)); } diff --git a/inst/extdata/gptools/graph.stan b/inst/extdata/gptools/graph.stan index ae98e58..8faf9ea 100644 --- a/inst/extdata/gptools/graph.stan +++ b/inst/extdata/gptools/graph.stan @@ -44,10 +44,17 @@ Evaluate the location and scale for a node given its predecessors, assuming zero :param epsilon: Nugget variance for numerical stability. :returns: Location and scale parameters for the distribution of the node given its predecessors. */ -vector gp_graph_conditional_loc_scale(vector y, array[] vector x, int kernel, real sigma, - real length_scale, int node, array [] int predecessors, - real epsilon) { +vector gp_graph_conditional_loc_scale( + vector y, array[] vector x, int kernel, real sigma, array [] real length_scale, + int node, array [] int predecessors, real epsilon +) { int k = size(predecessors); + + // If there are no predecessors, we simply use the marginal distribution. + if (k == 0) { + return [0, sqrt(sigma ^ 2 + epsilon)]'; + } + matrix[1, k] cov12; matrix[k, k] cov22; if (kernel == 0) { @@ -85,7 +92,8 @@ Evaluate the log probability of a graph Gaussian process. :returns: Log probability of the graph Gaussian process. */ real gp_graph_lpdf(vector y, vector loc, array [] vector x, int kernel, real sigma, - real length_scale, array [,] int edges, array[] int degrees, real epsilon) { + array [] real length_scale, array [,] int edges, array[] int degrees, real epsilon +) { real lpdf = 0; int offset_ = 1; vector[size(y)] z = y - loc; @@ -99,6 +107,39 @@ real gp_graph_lpdf(vector y, vector loc, array [] vector x, int kernel, real sig } +/** +Evaluate the log probability of a graph Gaussian process. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param kernel: Kernel to use (0 for squared exponential, 1 for Matern 3/2, 2 for Matern 5/2). +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_lpdf( + vector y, + vector loc, + array [] vector x, + int kernel, + real sigma, + real length_scale, + array [,] int edges, + array[] int degrees, + real epsilon +) { + int p = size(x[1]); + return gp_graph_lpdf(y | loc, x, kernel, sigma, rep_array(length_scale, p), edges, degrees, epsilon); +} + + /** Evaluate the log probability of a graph Gaussian process. @@ -121,6 +162,28 @@ real gp_graph_lpdf(vector y, vector loc, array [] vector x, int kernel, real sig } +/** +Evaluate the log probability of a graph Gaussian process. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param kernel: Kernel to use (0 for squared exponential, 1 for Matern 3/2, 2 for Matern 5/2). +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_lpdf(vector y, vector loc, array [] vector x, int kernel, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_graph_lpdf(y | loc, x, kernel, sigma, length_scale, edges, + out_degrees(size(y), edges), 1e-12); +} + + /** Transform white noise to a sample from a graph Gaussian process @@ -129,7 +192,7 @@ Transform white noise to a sample from a graph Gaussian process :param x: Position of each node. :param kernel: Kernel to use (0 for squared exponential, 1 for Matern 3/2, 2 for Matern 5/2). :param sigma: Marginal scale of the kernel. -:param length_scale: Correlation length of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. :param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row comprises parents of children in the second row. The first row can have arbitrary order, but the @@ -139,7 +202,8 @@ Transform white noise to a sample from a graph Gaussian process :returns: Sample from the Graph gaussian process. */ vector gp_inv_graph(vector z, vector loc, array [] vector x, int kernel, real sigma, - real length_scale, array [,] int edges, array [] int degrees, real epsilon) { + array [] real length_scale, array [,] int edges, array [] int degrees, real epsilon +) { vector[size(z)] y; int offset_ = 1; for (i in 1:size(x)) { @@ -165,14 +229,62 @@ Transform white noise to a sample from a graph Gaussian process as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row comprises parents of children in the second row. The first row can have arbitrary order, but the second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. :returns: Sample from the Graph gaussian process. */ vector gp_inv_graph(vector z, vector loc, array [] vector x, int kernel, real sigma, - real length_scale, array [,] int edges) { + real length_scale, array [,] int edges, array [] int degrees, real epsilon +) { + int p = size(x[1]); + return gp_inv_graph(z, loc, x, kernel, sigma, rep_array(length_scale, p), edges, degrees, epsilon); +} + + +/** +Transform white noise to a sample from a graph Gaussian process + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param kernel: Kernel to use (0 for squared exponential, 1 for Matern 3/2, 2 for Matern 5/2). +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph(vector z, vector loc, array [] vector x, int kernel, real sigma, + array [] real length_scale, array [,] int edges) { return gp_inv_graph(z, loc, x, kernel, sigma, length_scale, edges, out_degrees(size(z), edges), 1e-12); } + +/** +Transform white noise to a sample from a graph Gaussian process + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param kernel: Kernel to use (0 for squared exponential, 1 for Matern 3/2, 2 for Matern 5/2). +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph(vector z, vector loc, array [] vector x, int kernel, real sigma, + real length_scale, array [,] int edges) { + int p = size(x[1]); + return gp_inv_graph(z, loc, x, kernel, sigma, rep_array(length_scale, p), edges, + out_degrees(size(z), edges), 1e-12); +} + // Functions for graph Gaussian processes with squared exponential kernel -------------------------- /** @@ -198,6 +310,29 @@ real gp_graph_exp_quad_cov_lpdf(vector y, vector loc, array [] vector x, real si } +/** +Evaluate the log probability of a graph Gaussian with squared exponential kernel. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_exp_quad_cov_lpdf(vector y, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array[] int degrees, real epsilon +) { + return gp_graph_lpdf(y | loc, x, 0, sigma, length_scale, edges, degrees, epsilon); +} + + /** Evaluate the log probability of a graph Gaussian with squared exponential kernel. @@ -237,6 +372,32 @@ Transform white noise to a sample from a graph Gaussian process with squared exp vector gp_inv_graph_exp_quad_cov(vector z, vector loc, array [] vector x, real sigma, real length_scale, array [,] int edges, array [] int degrees, real epsilon) { + int p = size(x[1]); + return gp_inv_graph(z, loc, x, 0, sigma, rep_array(length_scale, p), edges, degrees, epsilon); +} + + +/** +Transform white noise to a sample from a graph Gaussian process with squared +exponential kernel and different length scales along each feature dimension. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation lengths of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic + graph. Edges are stored as a matrix with shape :code:`(2, m)`, where + :code:`m` is the number of edges. The first row comprises parents of + children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_exp_quad_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array [] int degrees, real epsilon +) { return gp_inv_graph(z, loc, x, 0, sigma, length_scale, edges, degrees, epsilon); } @@ -261,6 +422,26 @@ vector gp_inv_graph_exp_quad_cov(vector z, vector loc, array [] vector x, real s } +/** +Transform white noise to a sample from a graph Gaussian process with squared exponential kernel. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_exp_quad_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_inv_graph(z, loc, x, 0, sigma, length_scale, edges); +} + + // Functions for graph Gaussian processes with Matern 3 / 2 kernel --------------------------------- /** @@ -306,6 +487,49 @@ real gp_graph_matern32_cov_lpdf(vector y, vector loc, array [] vector x, real si } +/** +Evaluate the log probability of a graph Gaussian with Matern 3 / 2 kernel. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_matern32_cov_lpdf(vector y, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array[] int degrees, + real epsilon) { + return gp_graph_lpdf(y | loc, x, 1, sigma, length_scale, edges, degrees, epsilon); +} + + +/** +Evaluate the log probability of a graph Gaussian with Matern 3 / 2 kernel. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_matern32_cov_lpdf(vector y, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_graph_lpdf(y | loc, x, 1, sigma, length_scale, edges); +} + + /** Transform white noise to a sample from a graph Gaussian process with Matern 3 / 2 kernel. @@ -349,6 +573,49 @@ vector gp_inv_graph_matern32_cov(vector z, vector loc, array [] vector x, real s } +/** +Transform white noise to a sample from a graph Gaussian process with Matern 3 / 2 kernel. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_matern32_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array [] int degrees, + real epsilon) { + return gp_inv_graph(z, loc, x, 1, sigma, length_scale, edges, degrees, epsilon); +} + + +/** +Transform white noise to a sample from a graph Gaussian process with Matern 3 / 2 kernel. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_matern32_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_inv_graph(z, loc, x, 1, sigma, length_scale, edges); +} + + // Functions for graph Gaussian processes with Matern 5 / 2 kernel --------------------------------- /** @@ -394,6 +661,49 @@ real gp_graph_matern52_cov_lpdf(vector y, vector loc, array [] vector x, real si } +/** +Evaluate the log probability of a graph Gaussian with Matern 5 / 2 kernel. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_matern52_cov_lpdf(vector y, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array[] int degrees, + real epsilon) { + return gp_graph_lpdf(y | loc, x, 2, sigma, length_scale, edges, degrees, epsilon); +} + + +/** +Evaluate the log probability of a graph Gaussian with Matern 5 / 2 kernel. + +:param y: State of each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Log probability of the graph Gaussian process. +*/ +real gp_graph_matern52_cov_lpdf(vector y, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_graph_lpdf(y | loc, x, 2, sigma, length_scale, edges); +} + + /** Transform white noise to a sample from a graph Gaussian process with Matern 5 / 2 kernel. @@ -435,3 +745,46 @@ vector gp_inv_graph_matern52_cov(vector z, vector loc, array [] vector x, real s real length_scale, array [,] int edges) { return gp_inv_graph(z, loc, x, 2, sigma, length_scale, edges); } + + +/** +Transform white noise to a sample from a graph Gaussian process with Matern 5 / 2 kernel. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:param degrees: Out-degree of each node. +:param epsilon: Nugget variance for numerical stability. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_matern52_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges, array [] int degrees, + real epsilon) { + return gp_inv_graph(z, loc, x, 2, sigma, length_scale, edges, degrees, epsilon); +} + + +/** +Transform white noise to a sample from a graph Gaussian process with Matern 5 / 2 kernel. + +:param z: White noise for each node. +:param loc: Mean of each node. +:param x: Position of each node. +:param sigma: Marginal scale of the kernel. +:param length_scale: Correlation length of the kernel for each dimension. +:param edges: Directed edges between nodes constituting a directed acyclic graph. Edges are stored + as a matrix with shape :code:`(2, m)`, where :code:`m` is the number of edges. The first row + comprises parents of children in the second row. The first row can have arbitrary order, but the + second row must be sorted. +:returns: Sample from the Graph gaussian process. +*/ +vector gp_inv_graph_matern52_cov(vector z, vector loc, array [] vector x, real sigma, + array [] real length_scale, array [,] int edges) { + return gp_inv_graph(z, loc, x, 2, sigma, length_scale, edges); +}