Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dot_product.hpp
Go to the documentation of this file.
1 #ifndef STAN__AGRAD__REV__MATRIX__DOT_PRODUCT_HPP
2 #define STAN__AGRAD__REV__MATRIX__DOT_PRODUCT_HPP
3 
4 #include <vector>
5 #include <boost/utility/enable_if.hpp>
6 #include <boost/type_traits.hpp>
12 #include <stan/agrad/rev/var.hpp>
13 #include <stan/agrad/rev/vari.hpp>
16 
17 namespace stan {
18  namespace agrad {
19 
20  namespace {
21  template<typename T>
22  struct dot_product_store_type;
23 
24  template<>
25  struct dot_product_store_type<var> {
26  typedef vari** type;
27  };
28 
29  template<>
30  struct dot_product_store_type<double> {
31  typedef double* type;
32  };
33 
34  template<typename T1, typename T2>
35  class dot_product_vari : public vari {
36  protected:
37  typename dot_product_store_type<T1>::type v1_;
38  typename dot_product_store_type<T2>::type v2_;
39  size_t length_;
40 
41  inline static double var_dot(vari** v1, vari** v2,
42  size_t length) {
43  Eigen::VectorXd vd1(length), vd2(length);
44  for (size_t i = 0; i < length; i++) {
45  vd1[i] = v1[i]->val_;
46  vd2[i] = v2[i]->val_;
47  }
48  return vd1.dot(vd2);
49  }
50 
51  inline static double var_dot(const T1* v1, const T2* v2,
52  size_t length) {
54  Eigen::VectorXd vd1(length), vd2(length);
55  for (size_t i = 0; i < length; i++) {
56  vd1[i] = value_of(v1[i]);
57  vd2[i] = value_of(v2[i]);
58  }
59  return vd1.dot(vd2);
60  }
61 
62  template<typename Derived1,typename Derived2>
63  inline static double var_dot(const Eigen::DenseBase<Derived1> &v1,
64  const Eigen::DenseBase<Derived2> &v2) {
67  Eigen::VectorXd vd1(v1.size()), vd2(v1.size());
68  for (int i = 0; i < v1.size(); i++) {
69  vd1[i] = value_of(v1[i]);
70  vd2[i] = value_of(v2[i]);
71  }
72  return vd1.dot(vd2);
73  }
74  inline void chain(vari** v1, vari** v2) {
75  for (size_t i = 0; i < length_; i++) {
76  v1[i]->adj_ += adj_ * v2_[i]->val_;
77  v2[i]->adj_ += adj_ * v1_[i]->val_;
78  }
79  }
80  inline void chain(double* v1, vari** v2) {
81  for (size_t i = 0; i < length_; i++) {
82  v2[i]->adj_ += adj_ * v1_[i];
83  }
84  }
85  inline void chain(vari** v1, double* v2) {
86  for (size_t i = 0; i < length_; i++) {
87  v1[i]->adj_ += adj_ * v2_[i];
88  }
89  }
90  inline void initialize(vari** &mem_v, const var *inv, vari **shared = NULL) {
91  if (shared == NULL) {
92  mem_v = (vari**)memalloc_.alloc(length_*sizeof(vari*));
93  for (size_t i = 0; i < length_; i++)
94  mem_v[i] = inv[i].vi_;
95  }
96  else {
97  mem_v = shared;
98  }
99  }
100  template<typename Derived>
101  inline void initialize(vari** &mem_v, const Eigen::DenseBase<Derived> &inv, vari **shared = NULL) {
102  if (shared == NULL) {
103  mem_v = (vari**)memalloc_.alloc(length_*sizeof(vari*));
104  for (size_t i = 0; i < length_; i++)
105  mem_v[i] = inv(i).vi_;
106  }
107  else {
108  mem_v = shared;
109  }
110  }
111 
112  inline void initialize(double* &mem_d, const double *ind, double *shared = NULL) {
113  if (shared == NULL) {
114  mem_d = (double*)memalloc_.alloc(length_*sizeof(double));
115  for (size_t i = 0; i < length_; i++)
116  mem_d[i] = ind[i];
117  }
118  else {
119  mem_d = shared;
120  }
121  }
122  template<typename Derived>
123  inline void initialize(double* &mem_d, const Eigen::DenseBase<Derived> &ind, double *shared = NULL) {
124  if (shared == NULL) {
125  mem_d = (double*)memalloc_.alloc(length_*sizeof(double));
126  for (size_t i = 0; i < length_; i++)
127  mem_d[i] = ind(i);
128  }
129  else {
130  mem_d = shared;
131  }
132  }
133 
134  public:
135  dot_product_vari(typename dot_product_store_type<T1>::type v1,
136  typename dot_product_store_type<T2>::type v2,
137  size_t length)
138  : vari(var_dot(v1,v2,length)), v1_(v1), v2_(v2), length_(length) {}
139 
140  dot_product_vari(const T1* v1, const T2* v2, size_t length,
141  dot_product_vari<T1,T2>* shared_v1 = NULL,
142  dot_product_vari<T1,T2>* shared_v2 = NULL) :
143  vari(var_dot(v1, v2, length)), length_(length) {
144  if (shared_v1 == NULL) {
145  initialize(v1_,v1);
146  }
147  else {
148  initialize(v1_,v1,shared_v1->v1_);
149  }
150  if (shared_v2 == NULL) {
151  initialize(v2_,v2);
152  }
153  else {
154  initialize(v2_,v2,shared_v2->v2_);
155  }
156  }
157  template<typename Derived1,typename Derived2>
158  dot_product_vari(const Eigen::DenseBase<Derived1> &v1,
159  const Eigen::DenseBase<Derived2> &v2,
160  dot_product_vari<T1,T2>* shared_v1 = NULL,
161  dot_product_vari<T1,T2>* shared_v2 = NULL) :
162  vari(var_dot(v1, v2)), length_(v1.size()) {
163  if (shared_v1 == NULL) {
164  initialize(v1_,v1);
165  }
166  else {
167  initialize(v1_,v1,shared_v1->v1_);
168  }
169  if (shared_v2 == NULL) {
170  initialize(v2_,v2);
171  }
172  else {
173  initialize(v2_,v2,shared_v2->v2_);
174  }
175  }
176  template<int R1,int C1,int R2,int C2>
177  dot_product_vari(const Eigen::Matrix<T1,R1,C1> &v1,
178  const Eigen::Matrix<T2,R2,C2> &v2,
179  dot_product_vari<T1,T2>* shared_v1 = NULL,
180  dot_product_vari<T1,T2>* shared_v2 = NULL) :
181  vari(var_dot(v1, v2)), length_(v1.size()) {
182  if (shared_v1 == NULL) {
183  initialize(v1_,v1);
184  }
185  else {
186  initialize(v1_,v1,shared_v1->v1_);
187  }
188  if (shared_v2 == NULL) {
189  initialize(v2_,v2);
190  }
191  else {
192  initialize(v2_,v2,shared_v2->v2_);
193  }
194  }
195  virtual void chain() {
196  chain(v1_,v2_);
197  }
198  };
199  }
200 
209  template<typename T1, int R1, int C1, typename T2, int R2, int C2>
210  inline
211  typename boost::enable_if_c<boost::is_same<T1,var>::value ||
212  boost::is_same<T2,var>::value, var>::type
213  dot_product(const Eigen::Matrix<T1, R1, C1>& v1,
214  const Eigen::Matrix<T2, R2, C2>& v2) {
215  stan::math::check_vector("dot_product(%1%)",v1,"v1",(double*)0);
216  stan::math::check_vector("dot_product(%1%)",v2,"v2",(double*)0);
217  stan::math::check_matching_sizes("dot_product(%1%)",v1,"v1",
218  v2,"v2",(double*)0);
219  return var(new dot_product_vari<T1,T2>(v1,v2));
220  }
229  template<typename T1, typename T2>
230  inline
231  typename boost::enable_if_c<boost::is_same<T1,var>::value ||
232  boost::is_same<T2,var>::value, var>::type
233  dot_product(const T1* v1, const T2* v2, size_t length) {
234  return var(new dot_product_vari<T1,T2>(v1, v2, length));
235  }
236 
245  template<typename T1, typename T2>
246  inline
247  typename boost::enable_if_c<boost::is_same<T1,var>::value ||
248  boost::is_same<T2,var>::value, var>::type
249  dot_product(const std::vector<T1>& v1,
250  const std::vector<T2>& v2) {
251  stan::math::check_matching_sizes("dot_product(%1%)",v1,"v1",
252  v2,"v2",(double*)0);
253  return var(new dot_product_vari<T1,T2>(&v1[0], &v2[0], v1.size()));
254  }
255 
256  template<typename T1, int R1, int C1, typename T2, int R2, int C2>
257  inline
258  typename boost::enable_if_c<boost::is_same<T1,var>::value ||
259  boost::is_same<T2,var>::value,
260  Eigen::Matrix<var, 1, C1> >::type
261  columns_dot_product(const Eigen::Matrix<T1, R1, C1>& v1,
262  const Eigen::Matrix<T2, R2, C2>& v2) {
263  stan::math::check_matching_sizes("dot_product(%1%)",v1,"v1",
264  v2,"v2",(double*)0);
265  Eigen::Matrix<var, 1, C1> ret(1,v1.cols());
266  for (size_type j = 0; j < v1.cols(); ++j) {
267  ret(j) = var(new dot_product_vari<T1,T2>(v1.col(j),v2.col(j)));
268  }
269  return ret;
270  }
271 
272  template<typename T1, int R1, int C1, typename T2, int R2, int C2>
273  inline
274  typename boost::enable_if_c<boost::is_same<T1,var>::value ||
275  boost::is_same<T2,var>::value,
276  Eigen::Matrix<var, R1, 1> >::type
277  rows_dot_product(const Eigen::Matrix<T1, R1, C1>& v1,
278  const Eigen::Matrix<T2, R2, C2>& v2) {
279  stan::math::check_matching_sizes("dot_product(%1%)",v1,"v1",
280  v2,"v2",(double*)0);
281  Eigen::Matrix<var, R1, 1> ret(v1.rows(),1);
282  for (size_type j = 0; j < v1.rows(); ++j) {
283  ret(j) = var(new dot_product_vari<T1,T2>(v1.row(j),v2.row(j)));
284  }
285  return ret;
286  }
287  }
288 }
289 #endif
size_t length(const T &)
Definition: traits.hpp:159
memory::stack_alloc memalloc_
Definition: var_stack.cpp:16
bool check_vector(const char *function, const Eigen::Matrix< T, R, C > &x, const char *name, T_result *result)
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:16
void initialize(T &x, const T &v)
Definition: initialize.hpp:17
fvar< T > inv(const fvar< T > &x)
Definition: inv.hpp:15
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Definition: value_of.hpp:24
dot_product_store_type< T2 >::type v2_
Definition: dot_product.hpp:38
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic >::Index size_type
Definition: typedefs.hpp:14
fvar< T > dot_product(const Eigen::Matrix< fvar< T >, R1, C1 > &v1, const Eigen::Matrix< fvar< T >, R2, C2 > &v2)
Definition: dot_product.hpp:20
void * alloc(size_t len)
Return a newly allocated block of memory of the appropriate size managed by the stack allocator...
dot_product_store_type< T1 >::type v1_
Definition: dot_product.hpp:37
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:27
int size(const std::vector< T > &x)
Definition: size.hpp:11
Eigen::Matrix< fvar< T >, 1, C1 > columns_dot_product(const Eigen::Matrix< fvar< T >, R1, C1 > &v1, const Eigen::Matrix< fvar< T >, R2, C2 > &v2)
bool check_matching_sizes(const char *function, const T_y1 &y1, const char *name1, const T_y2 &y2, const char *name2, T_result *result)
size_t length_
Definition: dot_product.hpp:39
Eigen::Matrix< fvar< T >, R1, 1 > rows_dot_product(const Eigen::Matrix< fvar< T >, R1, C1 > &v1, const Eigen::Matrix< fvar< T >, R2, C2 > &v2)

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