1 #ifndef STAN_MATH_REV_MAT_FUN_GP_PERIODIC_COV_HPP 2 #define STAN_MATH_REV_MAT_FUN_GP_PERIODIC_COV_HPP 15 #include <type_traits> 54 template <
typename T_x,
typename T_sigma,
typename T_l,
typename T_p>
92 const T_l &l,
const T_p &p)
95 size_ltri_(size_ * (size_ - 1) / 2),
99 sigma_sq_d_(sigma_d_ * sigma_d_),
102 sin_2_dist_(
ChainableStack::instance_->memalloc_.alloc_array<double>(
104 sin_dist_sq_(
ChainableStack::instance_->memalloc_.alloc_array<double>(
107 sigma_vari_(sigma.vi_),
113 double neg_two_inv_l_sq = -2.0 / (l_d_ *
l_d_);
114 double pi_div_p =
pi() /
p_d_;
117 for (
size_t j = 0; j <
size_; ++j) {
118 for (
size_t i = j + 1; i <
size_; ++i) {
120 double sin_dist =
sin(pi_div_p * dist);
121 double sin_dist_sq =
square(sin_dist);
123 sin_2_dist_[pos] =
sin(2.0 * pi_div_p * dist);
124 sin_dist_sq_[pos] = sin_dist_sq;
125 cov_lower_[pos] =
new vari(
126 sigma_sq_d_ *
std::exp(sin_dist_sq * neg_two_inv_l_sq),
false);
129 cov_diag_[j] =
new vari(sigma_sq_d_,
false);
139 vari *el_low = cov_lower_[i];
140 double prod_add = el_low->
adj_ * el_low->
val_;
141 adjl += prod_add * sin_dist_sq_[i];
142 adjsigma += prod_add;
143 adjp += prod_add * sin_2_dist_[i] * dist_[i];
145 for (
size_t i = 0; i <
size_; ++i) {
146 vari *el = cov_diag_[i];
149 double l_d_sq = l_d_ *
l_d_;
150 l_vari_->
adj_ += adjl * 4 / (l_d_sq *
l_d_);
152 p_vari_->
adj_ += adjp * 2 *
pi() / l_d_sq / (p_d_ *
p_d_);
188 template <
typename T_x,
typename T_l,
typename T_p>
228 size_ltri_(size_ * (size_ - 1) / 2),
232 sigma_sq_d_(sigma_d_ * sigma_d_),
235 sin_2_dist_(
ChainableStack::instance_->memalloc_.alloc_array<double>(
237 sin_dist_sq_(
ChainableStack::instance_->memalloc_.alloc_array<double>(
245 double neg_two_inv_l_sq = -2.0 / (l_d_ *
l_d_);
246 double pi_div_p =
pi() /
p_d_;
249 for (
size_t j = 0; j <
size_; ++j) {
250 for (
size_t i = j + 1; i <
size_; ++i) {
252 double sin_dist =
sin(pi_div_p * dist);
253 double sin_dist_sq =
square(sin_dist);
255 sin_2_dist_[pos] =
sin(2.0 * pi_div_p * dist);
256 sin_dist_sq_[pos] = sin_dist_sq;
257 cov_lower_[pos] =
new vari(
258 sigma_sq_d_ *
std::exp(sin_dist_sq * neg_two_inv_l_sq),
false);
261 cov_diag_[j] =
new vari(sigma_sq_d_,
false);
270 vari *el_low = cov_lower_[i];
271 double prod_add = el_low->
adj_ * el_low->
val_;
272 adjl += prod_add * sin_dist_sq_[i];
273 adjp += prod_add * sin_2_dist_[i] * dist_[i];
275 double l_d_sq = l_d_ *
l_d_;
276 l_vari_->
adj_ += adjl * 4 / (l_d_sq *
l_d_);
277 p_vari_->
adj_ += adjp * 2 *
pi() / l_d_sq / (p_d_ *
p_d_);
300 template <
typename T_x>
301 inline typename std::enable_if<
302 std::is_same<typename scalar_type<T_x>::type,
double>::value,
303 Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic>>::type
306 const char *fun =
"gp_periodic_cov";
310 size_t x_size = x.size();
311 for (
size_t i = 0; i < x_size; ++i)
314 Eigen::Matrix<
var, -1, -1> cov(x_size, x_size);
322 for (
size_t j = 0; j < x_size; ++j) {
323 for (
size_t i = (j + 1); i < x_size; ++i) {
324 cov.coeffRef(i, j).vi_ = baseVari->
cov_lower_[pos];
325 cov.coeffRef(j, i).vi_ = cov.coeffRef(i, j).vi_;
328 cov.coeffRef(j, j).vi_ = baseVari->
cov_diag_[j];
352 template <
typename T_x>
353 inline typename std::enable_if<
354 std::is_same<typename scalar_type<T_x>::type,
double>::value,
355 Eigen::Matrix<var, Eigen::Dynamic, Eigen::Dynamic>>::type
358 const char *fun =
"gp_periodic_cov";
362 size_t x_size = x.size();
363 for (
size_t i = 0; i < x_size; ++i)
366 Eigen::Matrix<
var, -1, -1> cov(x_size, x_size);
374 for (
size_t j = 0; j < x_size - 1; ++j) {
375 for (
size_t i = (j + 1); i < x_size; ++i) {
376 cov.coeffRef(i, j).vi_ = baseVari->
cov_lower_[pos];
377 cov.coeffRef(j, i).vi_ = cov.coeffRef(i, j).vi_;
380 cov.coeffRef(j, j).vi_ = baseVari->
cov_diag_[j];
382 cov.coeffRef(x_size - 1, x_size - 1).vi_ = baseVari->
cov_diag_[x_size - 1];
This is a subclass of the vari class for precomputed gradients of gp_periodic_cov.
gp_periodic_cov_vari(const std::vector< T_x > &x, double sigma, const T_l &l, const T_p &p)
Constructor for gp_periodic_cov.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
The variable implementation base class.
Independent (input) and dependent (output) variables for gradients.
const double val_
The value of this variable.
fvar< T > square(const fvar< T > &x)
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
fvar< T > sin(const fvar< T > &x)
fvar< T > exp(const fvar< T > &x)
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
gp_periodic_cov_vari(const std::vector< T_x > &x, const T_sigma &sigma, const T_l &l, const T_p &p)
Constructor for gp_periodic_cov.
vari(double x)
Construct a variable implementation from a value.
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
boost::math::tools::promote_args< T1, T2 >::type distance(const Eigen::Matrix< T1, R1, C1 > &v1, const Eigen::Matrix< T2, R2, C2 > &v2)
Returns the distance between the specified vectors.
void check_positive(const char *function, const char *name, const T_y &y)
Check if y is positive.
double pi()
Return the value of pi.
double adj_
The adjoint of this variable, which is the partial derivative of this variable with respect to the ro...
This struct always provides access to the autodiff stack using the singleton pattern.
Eigen::Matrix< typename stan::return_type< T_x, T_sigma, T_l, T_p >::type, 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 .