Hello! I am currently fitting a bunch of Hilbert Space Gaussian Processes (HSGPs) with a partial pooling (similar to this PyMC example).
I am adopting/extending @avehtari Birthday example code to allow for fitting many HSGPs at once.
My question is how to “best” improve the defined diagSPD_periodic()
function to make it “vectorized”.
The current function accounts for a single sigma
and a single lengthscale
as follows:
vector diagSPD_periodic(real sigma, real lengthscale, int M) {
real a = inv_square(lengthscale);
vector[M] q = exp(log(sigma) + 0.5 * (log(2) - a + to_vector(log_modified_bessel_first_kind(linspaced_int_array(M, 1, M), a))));
return append_row(q,q);
}
but now I would like to pass in a vector
of sigma
and a vector
of lengthscale
and return a matrix
corresponding to the computation for each integer against each element of the vector.
My attempt is:
matrix diagSPD_periodic_M(vector sigma, vector lengthscale, int M) {
int num_gps = num_elements(sigma);
vector[num_gps] a = inv_square(lengthscale);
matrix[num_gps, M] linspaced_matrix = rep_matrix(linspaced_row_vector(M, 1, M), num_gps );
matrix[num_gps , M] expanded_parameter = rep_matrix(a,M);
matrix[num_gps ,M] q = exp(
log(rep_matrix(sigma,M)) + 0.5 * (log(2) - expanded_parameter + log_modified_bessel_first_kind(linspaced_matrix, expanded_parameter))
);
return append_col(q,q);
}
but it still seems inefficient?
My quesiton is: is this the best way to “vectorize” this function?
NOTE: I would also be willing to augment the C++ code to allow for passing in containers of different lengths and returning a matrix of the appropriate size (for the above code I adopted the code from the manual here)