Stan Math Library  2.9.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 
18  namespace math {
19 
20  namespace {
21 
22  class squared_distance_vv_vari : public vari {
23  protected:
24  vari** v1_;
25  vari** v2_;
26  size_t length_;
27 
28  template <int R1, int C1, int R2, int C2>
29  inline static double
30  var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
31  const Eigen::Matrix<var, R2, C2> &v2) {
32  using Eigen::Matrix;
34  typedef typename index_type<Matrix<var, R1, R2> >::type idx_t;
35  double result = 0;
36  for (idx_t i = 0; i < v1.size(); i++) {
37  double diff = v1(i).vi_->val_ - v2(i).vi_->val_;
38  result += diff*diff;
39  }
40  return result;
41  }
42 
43  public:
44  template<int R1, int C1, int R2, int C2>
45  squared_distance_vv_vari(const Eigen::Matrix<var, R1, C1> &v1,
46  const Eigen::Matrix<var, R2, C2> &v2)
47  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
48  v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
49  .alloc(length_*sizeof(vari*)));
50  for (size_t i = 0; i < length_; i++)
51  v1_[i] = v1(i).vi_;
52 
53  v2_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
54  .alloc(length_*sizeof(vari*)));
55  for (size_t i = 0; i < length_; i++)
56  v2_[i] = v2(i).vi_;
57  }
58  virtual void chain() {
59  for (size_t i = 0; i < length_; i++) {
60  double di = 2 * adj_ * (v1_[i]->val_ - v2_[i]->val_);
61  v1_[i]->adj_ += di;
62  v2_[i]->adj_ -= di;
63  }
64  }
65  };
66  class squared_distance_vd_vari : public vari {
67  protected:
68  vari** v1_;
69  double* v2_;
70  size_t length_;
71 
72  template<int R1, int C1, int R2, int C2>
73  inline static double
74  var_squared_distance(const Eigen::Matrix<var, R1, C1> &v1,
75  const Eigen::Matrix<double, R2, C2> &v2) {
76  using Eigen::Matrix;
78  typedef typename index_type<Matrix<double, R1, C1> >::type idx_t;
79 
80  double result = 0;
81  for (idx_t i = 0; i < v1.size(); i++) {
82  double diff = v1(i).vi_->val_ - v2(i);
83  result += diff*diff;
84  }
85  return result;
86  }
87 
88  public:
89  template<int R1, int C1, int R2, int C2>
90  squared_distance_vd_vari(const Eigen::Matrix<var, R1, C1> &v1,
91  const Eigen::Matrix<double, R2, C2> &v2)
92  : vari(var_squared_distance(v1, v2)), length_(v1.size()) {
93  v1_ = reinterpret_cast<vari**>(ChainableStack::memalloc_
94  .alloc(length_*sizeof(vari*)));
95  for (size_t i = 0; i < length_; i++)
96  v1_[i] = v1(i).vi_;
97 
98  v2_ = reinterpret_cast<double*>(ChainableStack::memalloc_
99  .alloc(length_*sizeof(double)));
100  for (size_t i = 0; i < length_; i++)
101  v2_[i] = v2(i);
102  }
103  virtual void chain() {
104  for (size_t i = 0; i < length_; i++) {
105  v1_[i]->adj_ += 2 * adj_ * (v1_[i]->val_ - v2_[i]);
106  }
107  }
108  };
109  }
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<var, R2, C2>& v2) {
114  stan::math::check_vector("squared_distance", "v1", v1);
115  stan::math::check_vector("squared_distance", "v2", v2);
116  stan::math::check_matching_sizes("squared_distance",
117  "v1", v1,
118  "v2", v2);
119  return var(new squared_distance_vv_vari(v1, v2));
120  }
121  template<int R1, int C1, int R2, int C2>
122  inline var squared_distance(const Eigen::Matrix<var, R1, C1>& v1,
123  const Eigen::Matrix<double, R2, C2>& v2) {
124  stan::math::check_vector("squared_distance", "v1", v1);
125  stan::math::check_vector("squared_distance", "v2", v2);
126  stan::math::check_matching_sizes("squared_distance",
127  "v1", v1,
128  "v2", v2);
129  return var(new squared_distance_vd_vari(v1, v2));
130  }
131  template<int R1, int C1, int R2, int C2>
132  inline var squared_distance(const Eigen::Matrix<double, R1, C1>& v1,
133  const Eigen::Matrix<var, R2, C2>& v2) {
134  stan::math::check_vector("squared_distance", "v1", v1);
135  stan::math::check_vector("squared_distance", "v2", v2);
136  stan::math::check_matching_sizes("squared_distance",
137  "v1", v1,
138  "v2", v2);
139  return var(new squared_distance_vd_vari(v2, v1));
140  }
141  }
142 }
143 #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.
boost::math::tools::promote_args< T1, T2 >::type squared_distance(const Eigen::Matrix< T1, R1, C1 > &v1, const Eigen::Matrix< T2, R2, C2 > &v2)
Returns the squared distance between the specified vectors.
vari ** v1_
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:31
Primary template class for the metaprogram to compute the index type of a container.
Definition: index_type.hpp:19
size_t length_
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–2015, Stan Development Team.