Stan Math Library  2.15.0
reverse mode automatic differentiation
fma.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_SCAL_FUN_FMA_HPP
2 #define STAN_MATH_REV_SCAL_FUN_FMA_HPP
3 
4 #include <stan/math/rev/core.hpp>
9 #include <limits>
10 
11 namespace stan {
12  namespace math {
13 
14  namespace {
15  class fma_vvv_vari : public op_vvv_vari {
16  public:
17  fma_vvv_vari(vari* avi, vari* bvi, vari* cvi) :
18  op_vvv_vari(fma(avi->val_, bvi->val_, cvi->val_), avi, bvi, cvi) {
19  }
20  void chain() {
21  if (unlikely(is_nan(avi_->val_)
22  || is_nan(bvi_->val_)
23  || is_nan(cvi_->val_))) {
24  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
25  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
26  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
27  } else {
28  avi_->adj_ += adj_ * bvi_->val_;
29  bvi_->adj_ += adj_ * avi_->val_;
30  cvi_->adj_ += adj_;
31  }
32  }
33  };
34 
35  class fma_vvd_vari : public op_vvd_vari {
36  public:
37  fma_vvd_vari(vari* avi, vari* bvi, double c) :
38  op_vvd_vari(fma(avi->val_, bvi->val_, c), avi, bvi, c) {
39  }
40  void chain() {
41  if (unlikely(is_nan(avi_->val_)
42  || is_nan(bvi_->val_)
43  || is_nan(cd_))) {
44  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
45  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
46  } else {
47  avi_->adj_ += adj_ * bvi_->val_;
48  bvi_->adj_ += adj_ * avi_->val_;
49  }
50  }
51  };
52 
53  class fma_vdv_vari : public op_vdv_vari {
54  public:
55  fma_vdv_vari(vari* avi, double b, vari* cvi) :
56  op_vdv_vari(fma(avi->val_ , b, cvi->val_), avi, b, cvi) {
57  }
58  void chain() {
59  if (unlikely(is_nan(avi_->val_)
60  || is_nan(cvi_->val_)
61  || is_nan(bd_))) {
62  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
63  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
64  } else {
65  avi_->adj_ += adj_ * bd_;
66  cvi_->adj_ += adj_;
67  }
68  }
69  };
70 
71  class fma_vdd_vari : public op_vdd_vari {
72  public:
73  fma_vdd_vari(vari* avi, double b, double c) :
74  op_vdd_vari(fma(avi->val_ , b, c), avi, b, c) {
75  }
76  void chain() {
77  if (unlikely(is_nan(avi_->val_)
78  || is_nan(bd_)
79  || is_nan(cd_)))
80  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
81  else
82  avi_->adj_ += adj_ * bd_;
83  }
84  };
85 
86  class fma_ddv_vari : public op_ddv_vari {
87  public:
88  fma_ddv_vari(double a, double b, vari* cvi) :
89  op_ddv_vari(fma(a, b, cvi->val_), a, b, cvi) {
90  }
91  void chain() {
92  if (unlikely(is_nan(cvi_->val_)
93  || is_nan(ad_)
94  || is_nan(bd_)))
95  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
96  else
97  cvi_->adj_ += adj_;
98  }
99  };
100  }
101 
120  inline var fma(const var& a, const var& b, const var& c) {
121  return var(new fma_vvv_vari(a.vi_, b.vi_, c.vi_));
122  }
123 
140  inline var fma(const var& a, const var& b, double c) {
141  return var(new fma_vvd_vari(a.vi_, b.vi_, c));
142  }
143 
160  inline var fma(const var& a, double b, const var& c) {
161  return var(new fma_vdv_vari(a.vi_, b, c.vi_));
162  }
163 
181  inline var fma(const var& a, double b, double c) {
182  return var(new fma_vdd_vari(a.vi_, b, c));
183  }
184 
199  inline var fma(double a, const var& b, double c) {
200  return var(new fma_vdd_vari(b.vi_, a, c));
201  }
202 
217  inline var fma(double a, double b, const var& c) {
218  return var(new fma_ddv_vari(a, b, c.vi_));
219  }
220 
237  inline var fma(double a, const var& b, const var& c) {
238  return var(new fma_vdv_vari(b.vi_, a, c.vi_)); // a-b symmetry
239  }
240 
241  }
242 }
243 #endif
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:30
#define unlikely(x)
Definition: likely.hpp:9
fvar< typename stan::return_type< T1, T2, T3 >::type > fma(const fvar< T1 > &x1, const fvar< T2 > &x2, const fvar< T3 > &x3)
The fused multiply-add operation (C99).
Definition: fma.hpp:61
vari * vi_
Pointer to the implementation of this variable.
Definition: var.hpp:42
int is_nan(const fvar< T > &x)
Returns 1 if the input&#39;s value is NaN and 0 otherwise.
Definition: is_nan.hpp:21

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