1#ifndef STAN_MATH_REV_FUN_GP_PERIODIC_COV_HPP
2#define STAN_MATH_REV_FUN_GP_PERIODIC_COV_HPP
40template <
typename T_x,
typename T_sigma, require_st_arithmetic<T_x>* =
nullptr,
41 require_stan_scalar_t<T_sigma>* =
nullptr>
43 const std::vector<T_x>& x,
const T_sigma sigma,
const var l,
const var p) {
46 const char* fun =
"gp_periodic_cov";
50 size_t x_size = x.size();
51 for (
size_t i = 0; i < x_size; ++i) {
55 Eigen::Matrix<
var, -1, -1> cov(x_size, x_size);
59 size_t l_tri_size = x_size * (x_size - 1) / 2;
70 size_t block_size = 10;
72 for (
size_t jb = 0; jb < x_size; jb += block_size) {
73 size_t j_end = std::min(x_size, jb + block_size);
74 size_t j_size = j_end - jb;
75 cov.diagonal().segment(jb, j_size)
76 = Eigen::VectorXd::Constant(j_size, sigma_sq);
79 cov_diag.segment(jb, j_size) = cov.diagonal().segment(jb, j_size);
81 for (
size_t ib = jb; ib < x_size; ib += block_size) {
82 size_t i_end = std::min(x_size, ib + block_size);
83 for (
size_t j = jb; j < j_end; ++j) {
84 for (
size_t i = std::max(ib, j + 1); i < i_end; ++i) {
86 double sin_dist =
sin(pi_div_p * dist);
87 double sin_dist_sq =
square(sin_dist);
88 dists_lin.coeffRef(pos) = dist;
89 sin_dists_sq_lin.coeffRef(pos) = sin_dist_sq;
90 cov_l_tri_lin.coeffRef(pos) = cov.coeffRef(j, i) = cov.coeffRef(i, j)
91 = sigma_sq *
exp(sin_dist_sq * neg_two_inv_l_sq);
99 sigma, l, p, x_size]() {
100 size_t l_tri_size = x_size * (x_size - 1) / 2;
103 double two_pi_div_p =
TWO_PI / p_val;
109 for (
size_t pos = 0; pos < l_tri_size; ++pos) {
111 = cov_l_tri_lin.coeff(pos).val() * cov_l_tri_lin.coeff(pos).adj();
112 adjl += prod_add * sin_dists_sq_lin.coeff(pos);
113 adjsigma += prod_add;
114 double dist = dists_lin.coeff(pos);
115 adjp += prod_add *
sin(two_pi_div_p * dist) * dist;
118 adjsigma += (cov_diag.val().array() * cov_diag.adj().array()).
sum();
121 double l_sq =
square(l_val);
122 l.adj() += adjl * 4 / (l_sq * l_val);
Equivalent to Eigen::Matrix, except that the data is stored on AD stack.
fvar< T > sin(const fvar< T > &x)
auto distance(const T_a &a, const T_b &b)
Returns the distance between the specified vectors.
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
auto & adjoint_of(const T &x)
Returns a reference to a variable's adjoint.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
Eigen::Matrix< return_type_t< T_x, T_sigma, T_l, T_p >, Eigen::Dynamic, Eigen::Dynamic > gp_periodic_cov(const std::vector< T_x > &x, const T_sigma &sigma, const T_l &l, const T_p &p)
Returns a periodic covariance matrix using the input .
auto sum(const std::vector< T > &m)
Return the sum of the entries of the specified standard vector.
static constexpr double TWO_PI
Twice the value of , .
void check_positive(const char *function, const char *name, const T_y &y)
Check if y is positive.
static constexpr double pi()
Return the value of pi.
fvar< T > square(const fvar< T > &x)
fvar< T > exp(const fvar< T > &x)
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Metaprogramming struct to detect whether a given type is constant in the mathematical sense (not the ...