Stan Math Library  2.20.0
reverse mode automatic differentiation
squared_distance.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_MAT_FUN_SQUARED_DISTANCE_HPP
2 #define STAN_MATH_REV_MAT_FUN_SQUARED_DISTANCE_HPP
3 
4 #include <stan/math/rev/meta.hpp>
5 #include <stan/math/rev/core.hpp>
9 #include <vector>
10 
11 namespace stan {
12 namespace math {
13 
14 namespace internal {
15 
17  protected:
18  vari** v1_;
19  vari** v2_;
20  size_t length_;
21 
22  template <int R1, int C1, int R2, int C2>
23  inline static double var_squared_distance(
24  const Eigen::Matrix<var, R1, C1>& v1,
25  const Eigen::Matrix<var, R2, C2>& v2) {
26  using Eigen::Matrix;
27  typedef typename index_type<Matrix<var, R1, R2> >::type idx_t;
28  double result = 0;
29  for (idx_t i = 0; i < v1.size(); i++) {
30  double diff = v1(i).vi_->val_ - v2(i).vi_->val_;
31  result += diff * diff;
32  }
33  return result;
34  }
35 
36  public:
37  template <int R1, int C1, int R2, int C2>
38  squared_distance_vv_vari(const Eigen::Matrix<var, R1, C1>& v1,
39  const Eigen::Matrix<var, R2, C2>& v2)
40  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
41  v1_ = reinterpret_cast<vari**>(
42  ChainableStack::instance_->memalloc_.alloc(length_ * sizeof(vari*)));
43  for (size_t i = 0; i < length_; i++)
44  v1_[i] = v1(i).vi_;
45 
46  v2_ = reinterpret_cast<vari**>(
47  ChainableStack::instance_->memalloc_.alloc(length_ * sizeof(vari*)));
48  for (size_t i = 0; i < length_; i++)
49  v2_[i] = v2(i).vi_;
50  }
51  virtual void chain() {
52  for (size_t i = 0; i < length_; i++) {
53  double di = 2 * adj_ * (v1_[i]->val_ - v2_[i]->val_);
54  v1_[i]->adj_ += di;
55  v2_[i]->adj_ -= di;
56  }
57  }
58 };
60  protected:
61  vari** v1_;
62  double* v2_;
63  size_t length_;
64 
65  template <int R1, int C1, int R2, int C2>
66  inline static double var_squared_distance(
67  const Eigen::Matrix<var, R1, C1>& v1,
68  const Eigen::Matrix<double, R2, C2>& v2) {
69  using Eigen::Matrix;
70  typedef typename index_type<Matrix<double, R1, C1> >::type idx_t;
71 
72  double result = 0;
73  for (idx_t i = 0; i < v1.size(); i++) {
74  double diff = v1(i).vi_->val_ - v2(i);
75  result += diff * diff;
76  }
77  return result;
78  }
79 
80  public:
81  template <int R1, int C1, int R2, int C2>
82  squared_distance_vd_vari(const Eigen::Matrix<var, R1, C1>& v1,
83  const Eigen::Matrix<double, R2, C2>& v2)
84  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
85  v1_ = reinterpret_cast<vari**>(
86  ChainableStack::instance_->memalloc_.alloc(length_ * sizeof(vari*)));
87  for (size_t i = 0; i < length_; i++)
88  v1_[i] = v1(i).vi_;
89 
90  v2_ = reinterpret_cast<double*>(
91  ChainableStack::instance_->memalloc_.alloc(length_ * sizeof(double)));
92  for (size_t i = 0; i < length_; i++)
93  v2_[i] = v2(i);
94  }
95  virtual void chain() {
96  for (size_t i = 0; i < length_; i++) {
97  v1_[i]->adj_ += 2 * adj_ * (v1_[i]->val_ - v2_[i]);
98  }
99  }
100 };
101 } // namespace internal
102 
103 template <int R1, int C1, int R2, int C2>
104 inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
105  const Eigen::Matrix<var, R2, C2>& v2) {
106  check_vector("squared_distance", "v1", v1);
107  check_vector("squared_distance", "v2", v2);
108  check_matching_sizes("squared_distance", "v1", v1, "v2", v2);
109  return var(new internal::squared_distance_vv_vari(v1, v2));
110 }
111 template <int R1, int C1, int R2, int C2>
112 inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
113  const Eigen::Matrix<double, R2, C2>& v2) {
114  check_vector("squared_distance", "v1", v1);
115  check_vector("squared_distance", "v2", v2);
116  check_matching_sizes("squared_distance", "v1", v1, "v2", v2);
117  return var(new internal::squared_distance_vd_vari(v1, v2));
118 }
119 template <int R1, int C1, int R2, int C2>
120 inline var squared_distance(const Eigen::Matrix<double, R1, C1>& v1,
121  const Eigen::Matrix<var, R2, C2>& v2) {
122  check_vector("squared_distance", "v1", v1);
123  check_vector("squared_distance", "v2", v2);
124  check_matching_sizes("squared_distance", "v1", v1, "v2", v2);
125  return var(new internal::squared_distance_vd_vari(v2, v1));
126 }
127 
128 } // namespace math
129 } // namespace stan
130 #endif
static double var_squared_distance(const Eigen::Matrix< var, R1, C1 > &v1, const Eigen::Matrix< var, R2, C2 > &v2)
The variable implementation base class.
Definition: vari.hpp:30
void check_vector(const char *function, const char *name, const Eigen::Matrix< T, R, C > &x)
Check if the matrix is either a row vector or column vector.
static STAN_THREADS_DEF AutodiffStackStorage * instance_
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:33
friend class var
Definition: vari.hpp:32
const double val_
The value of this variable.
Definition: vari.hpp:38
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
Primary template class for the metaprogram to compute the index type of a container.
Definition: index_type.hpp:18
fvar< T > squared_distance(const Eigen::Matrix< fvar< T >, R, C > &v1, const Eigen::Matrix< double, R, C > &v2)
Returns the squared distance between the specified vectors of the same dimensions.
squared_distance_vv_vari(const Eigen::Matrix< var, R1, C1 > &v1, const Eigen::Matrix< var, R2, C2 > &v2)
squared_distance_vd_vari(const Eigen::Matrix< var, R1, C1 > &v1, const Eigen::Matrix< double, R2, C2 > &v2)
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17
void check_matching_sizes(const char *function, const char *name1, const T_y1 &y1, const char *name2, const T_y2 &y2)
Check if two structures at the same size.
double adj_
The adjoint of this variable, which is the partial derivative of this variable with respect to the ro...
Definition: vari.hpp:44
static double var_squared_distance(const Eigen::Matrix< var, R1, C1 > &v1, const Eigen::Matrix< double, R2, C2 > &v2)
void * alloc(size_t len)
Return a newly allocated block of memory of the appropriate size managed by the stack allocator...

     [ Stan Home Page ] © 2011–2018, Stan Development Team.