1#ifndef STAN_MATH_REV_FUN_GP_PERIODIC_COV_HPP
2#define STAN_MATH_REV_FUN_GP_PERIODIC_COV_HPP
43template <
typename T_x,
typename T_sigma, require_st_arithmetic<T_x>* =
nullptr,
44 require_stan_scalar_t<T_sigma>* =
nullptr>
46 const std::vector<T_x>& x,
const T_sigma sigma,
const var l,
const var p) {
47 const char* fun =
"gp_periodic_cov";
51 size_t x_size = x.size();
52 for (
size_t i = 0; i < x_size; ++i) {
56 Eigen::Matrix<
var, -1, -1> cov(x_size, x_size);
60 size_t l_tri_size = x_size * (x_size - 1) / 2;
71 size_t block_size = 10;
73 for (
size_t jb = 0; jb < x_size; jb += block_size) {
74 size_t j_end = std::min(x_size, jb + block_size);
75 size_t j_size = j_end - jb;
76 cov.diagonal().segment(jb, j_size)
77 = Eigen::VectorXd::Constant(j_size, sigma_sq);
80 cov_diag.segment(jb, j_size) = cov.diagonal().segment(jb, j_size);
82 for (
size_t ib = jb; ib < x_size; ib += block_size) {
83 size_t i_end = std::min(x_size, ib + block_size);
84 for (
size_t j = jb; j < j_end; ++j) {
85 for (
size_t i = std::max(ib, j + 1); i < i_end; ++i) {
87 double sin_dist =
sin(pi_div_p * dist);
88 double sin_dist_sq =
square(sin_dist);
89 dists_lin.coeffRef(pos) = dist;
90 sin_dists_sq_lin.coeffRef(pos) = sin_dist_sq;
91 cov_l_tri_lin.coeffRef(pos) = cov.coeffRef(j, i) = cov.coeffRef(i, j)
92 = sigma_sq *
exp(sin_dist_sq * neg_two_inv_l_sq);
100 sigma, l, p, x_size]() {
101 size_t l_tri_size = x_size * (x_size - 1) / 2;
104 double two_pi_div_p =
TWO_PI / p_val;
110 for (
size_t pos = 0; pos < l_tri_size; ++pos) {
112 = cov_l_tri_lin.coeff(pos).val() * cov_l_tri_lin.coeff(pos).adj();
113 adjl += prod_add * sin_dists_sq_lin.coeff(pos);
114 adjsigma += prod_add;
115 double dist = dists_lin.coeff(pos);
116 adjp += prod_add *
sin(two_pi_div_p * dist) * dist;
119 adjsigma += (cov_diag.val().array() * cov_diag.adj().array()).
sum();
122 double l_sq =
square(l_val);
123 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 ...