Stan Math Library  2.12.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/core.hpp>
14 #include <vector>
15 
16 namespace stan {
17  namespace math {
18 
19  namespace {
20 
21  class squared_distance_vv_vari : public vari {
22  protected:
23  vari** v1_;
24  vari** v2_;
25  size_t length_;
26 
27  template <int R1, int C1, int R2, int C2>
28  inline static double
29  var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
30  const Eigen::Matrix<var, R2, C2> &v2) {
31  using Eigen::Matrix;
32  typedef typename index_type<Matrix<var, R1, R2> >::type idx_t;
33  double result = 0;
34  for (idx_t i = 0; i < v1.size(); i++) {
35  double diff = v1(i).vi_->val_ - v2(i).vi_->val_;
36  result += diff*diff;
37  }
38  return result;
39  }
40 
41  public:
42  template<int R1, int C1, int R2, int C2>
43  squared_distance_vv_vari(const Eigen::Matrix<var, R1, C1> &v1,
44  const Eigen::Matrix<var, R2, C2> &v2)
45  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
46  v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
47  .alloc(length_*sizeof(vari*)));
48  for (size_t i = 0; i < length_; i++)
49  v1_[i] = v1(i).vi_;
50 
51  v2_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
52  .alloc(length_*sizeof(vari*)));
53  for (size_t i = 0; i < length_; i++)
54  v2_[i] = v2(i).vi_;
55  }
56  virtual void chain() {
57  for (size_t i = 0; i < length_; i++) {
58  double di = 2 * adj_ * (v1_[i]->val_ - v2_[i]->val_);
59  v1_[i]->adj_ += di;
60  v2_[i]->adj_ -= di;
61  }
62  }
63  };
64  class squared_distance_vd_vari : public vari {
65  protected:
66  vari** v1_;
67  double* v2_;
68  size_t length_;
69 
70  template<int R1, int C1, int R2, int C2>
71  inline static double
72  var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
73  const Eigen::Matrix<double, R2, C2> &v2) {
74  using Eigen::Matrix;
75  typedef typename index_type<Matrix<double, R1, C1> >::type idx_t;
76 
77  double result = 0;
78  for (idx_t i = 0; i < v1.size(); i++) {
79  double diff = v1(i).vi_->val_ - v2(i);
80  result += diff*diff;
81  }
82  return result;
83  }
84 
85  public:
86  template<int R1, int C1, int R2, int C2>
87  squared_distance_vd_vari(const Eigen::Matrix<var, R1, C1> &v1,
88  const Eigen::Matrix<double, R2, C2> &v2)
89  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
90  v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
91  .alloc(length_*sizeof(vari*)));
92  for (size_t i = 0; i < length_; i++)
93  v1_[i] = v1(i).vi_;
94 
95  v2_ = reinterpret_cast<double*>(ChainableStack::memalloc_
96  .alloc(length_*sizeof(double)));
97  for (size_t i = 0; i < length_; i++)
98  v2_[i] = v2(i);
99  }
100  virtual void chain() {
101  for (size_t i = 0; i < length_; i++) {
102  v1_[i]->adj_ += 2 * adj_ * (v1_[i]->val_ - v2_[i]);
103  }
104  }
105  };
106  }
107 
108  template<int R1, int C1, int R2, int C2>
109  inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
110  const Eigen::Matrix<var, R2, C2>& v2) {
111  check_vector("squared_distance", "v1", v1);
112  check_vector("squared_distance", "v2", v2);
113  check_matching_sizes("squared_distance",
114  "v1", v1,
115  "v2", v2);
116  return var(new squared_distance_vv_vari(v1, v2));
117  }
118  template<int R1, int C1, int R2, int C2>
119  inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
120  const Eigen::Matrix<double, R2, C2>& v2) {
121  check_vector("squared_distance", "v1", v1);
122  check_vector("squared_distance", "v2", v2);
123  check_matching_sizes("squared_distance",
124  "v1", v1,
125  "v2", v2);
126  return var(new squared_distance_vd_vari(v1, v2));
127  }
128  template<int R1, int C1, int R2, int C2>
129  inline var squared_distance(const Eigen::Matrix<double, R1, C1>& v1,
130  const Eigen::Matrix<var, R2, C2>& v2) {
131  check_vector("squared_distance", "v1", v1);
132  check_vector("squared_distance", "v2", v2);
133  check_matching_sizes("squared_distance",
134  "v1", v1,
135  "v2", v2);
136  return var(new squared_distance_vd_vari(v2, v1));
137  }
138 
139  }
140 }
141 #endif
bool check_vector(const char *function, const char *name, const Eigen::Matrix< T, R, C > &x)
Return true if the matrix is either a row vector or column vector.
vari ** v1_
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:30
size_t length_
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.
bool check_matching_sizes(const char *function, const char *name1, const T_y1 &y1, const char *name2, const T_y2 &y2)
Return true if two structures at the same size.
vari ** v2_
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17
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–2016, Stan Development Team.