Automatic Differentiation
 
Loading...
Searching...
No Matches
cov_exp_quad.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_COV_EXP_QUAD_HPP
2#define STAN_MATH_REV_FUN_COV_EXP_QUAD_HPP
3
12#include <type_traits>
13#include <vector>
14#include <cmath>
15
16namespace stan {
17namespace math {
18
22template <typename T_x, typename T_sigma, typename T_l>
23class cov_exp_quad_vari : public vari {
24 public:
25 const size_t size_;
26 const size_t size_ltri_;
27 const double l_d_;
28 const double sigma_d_;
29 const double sigma_sq_d_;
30 double* dist_;
35
39 cov_exp_quad_vari(const std::vector<T_x>& x, const T_sigma& sigma,
40 const T_l& l)
41 : vari(0.0),
42 size_(x.size()),
43 size_ltri_(size_ * (size_ - 1) / 2),
44 l_d_(value_of(l)),
45 sigma_d_(value_of(sigma)),
47 dist_(ChainableStack::instance_->memalloc_.alloc_array<double>(
48 size_ltri_)),
49 l_vari_(l.vi_),
50 sigma_vari_(sigma.vi_),
51 cov_lower_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
52 size_ltri_)),
54 ChainableStack::instance_->memalloc_.alloc_array<vari*>(size_)) {
55 double inv_half_sq_l_d = 0.5 / (l_d_ * l_d_);
56 size_t pos = 0;
57 for (size_t j = 0; j < size_ - 1; ++j) {
58 for (size_t i = j + 1; i < size_; ++i) {
59 double dist_sq = squared_distance(x[i], x[j]);
60 dist_[pos] = dist_sq;
61 cov_lower_[pos] = new vari(
62 sigma_sq_d_ * std::exp(-dist_sq * inv_half_sq_l_d), false);
63 ++pos;
64 }
65 }
66 for (size_t i = 0; i < size_; ++i) {
67 cov_diag_[i] = new vari(sigma_sq_d_, false);
68 }
69 }
70
71 virtual void chain() {
72 double adjl = 0;
73 double adjsigma = 0;
74
75 for (size_t i = 0; i < size_ltri_; ++i) {
76 vari* el_low = cov_lower_[i];
77 double prod_add = el_low->adj_ * el_low->val_;
78 adjl += prod_add * dist_[i];
79 adjsigma += prod_add;
80 }
81 for (size_t i = 0; i < size_; ++i) {
82 vari* el = cov_diag_[i];
83 adjsigma += el->adj_ * el->val_;
84 }
85 l_vari_->adj_ += adjl / (l_d_ * l_d_ * l_d_);
86 sigma_vari_->adj_ += adjsigma * 2 / sigma_d_;
87 }
88};
89
93template <typename T_x, typename T_l>
94class cov_exp_quad_vari<T_x, double, T_l> : public vari {
95 public:
96 const size_t size_;
97 const size_t size_ltri_;
98 const double l_d_;
99 const double sigma_d_;
100 const double sigma_sq_d_;
101 double* dist_;
105
109 cov_exp_quad_vari(const std::vector<T_x>& x, double sigma, const T_l& l)
110 : vari(0.0),
111 size_(x.size()),
112 size_ltri_(size_ * (size_ - 1) / 2),
113 l_d_(value_of(l)),
114 sigma_d_(value_of(sigma)),
116 dist_(ChainableStack::instance_->memalloc_.alloc_array<double>(
117 size_ltri_)),
118 l_vari_(l.vi_),
119 cov_lower_(ChainableStack::instance_->memalloc_.alloc_array<vari*>(
120 size_ltri_)),
121 cov_diag_(
122 ChainableStack::instance_->memalloc_.alloc_array<vari*>(size_)) {
123 double inv_half_sq_l_d = 0.5 / (l_d_ * l_d_);
124 size_t pos = 0;
125 for (size_t j = 0; j < size_ - 1; ++j) {
126 for (size_t i = j + 1; i < size_; ++i) {
127 double dist_sq = squared_distance(x[i], x[j]);
128 dist_[pos] = dist_sq;
129 cov_lower_[pos] = new vari(
130 sigma_sq_d_ * std::exp(-dist_sq * inv_half_sq_l_d), false);
131 ++pos;
132 }
133 }
134 for (size_t i = 0; i < size_; ++i) {
135 cov_diag_[i] = new vari(sigma_sq_d_, false);
136 }
137 }
138
139 virtual void chain() {
140 double adjl = 0;
141
142 for (size_t i = 0; i < size_ltri_; ++i) {
143 vari* el_low = cov_lower_[i];
144 adjl += el_low->adj_ * el_low->val_ * dist_[i];
145 }
146 l_vari_->adj_ += adjl / (l_d_ * l_d_ * l_d_);
147 }
148};
149
153template <typename T_x,
155inline Eigen::Matrix<var, -1, -1> cov_exp_quad(const std::vector<T_x>& x,
156 const var& sigma, const var& l) {
157 return gp_exp_quad_cov(x, sigma, l);
158}
159
163template <typename T_x,
165inline Eigen::Matrix<var, -1, -1> cov_exp_quad(const std::vector<T_x>& x,
166 double sigma, const var& l) {
167 return gp_exp_quad_cov(x, sigma, l);
168}
169
170} // namespace math
171} // namespace stan
172#endif
cov_exp_quad_vari(const std::vector< T_x > &x, double sigma, const T_l &l)
cov_exp_quad_vari(const std::vector< T_x > &x, const T_sigma &sigma, const T_l &l)
require_t< std::is_arithmetic< std::decay_t< T > > > require_arithmetic_t
Require type satisfies std::is_arithmetic.
matrix_cl< return_type_t< T1, T2, T3 > > gp_exp_quad_cov(const matrix_cl< T1 > &x, const T2 sigma, const T3 length_scale)
Squared exponential kernel on the GPU.
int64_t size(const T &m)
Returns the size (number of the elements) of a matrix_cl or var_value<matrix_cl<T>>.
Definition size.hpp:19
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition value_of.hpp:18
vari_value< double > vari
Definition vari.hpp:197
Eigen::Matrix< return_type_t< T_x, T_sigma, T_l >, Eigen::Dynamic, Eigen::Dynamic > cov_exp_quad(const std::vector< T_x > &x, const T_sigma &sigma, const T_l &length_scale)
var_value< double > var
Definition var.hpp:1187
auto squared_distance(const T_a &a, const T_b &b)
Returns the squared distance.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
This struct always provides access to the autodiff stack using the singleton pattern.