Stan Math Library  2.6.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros
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 <math.h>
5 #include <stan/math/rev/core.hpp>
7 #include <boost/math/special_functions/fpclassify.hpp>
9 #include <valarray>
10 #include <limits>
11 
12 namespace stan {
13  namespace math {
14 
15  namespace {
16  class fma_vvv_vari : public op_vvv_vari {
17  public:
18  fma_vvv_vari(vari* avi, vari* bvi, vari* cvi) :
19  op_vvv_vari(::fma(avi->val_, bvi->val_, cvi->val_),
20  avi, bvi, cvi) {
21  }
22  void chain() {
23  if (unlikely(boost::math::isnan(avi_->val_)
24  || boost::math::isnan(bvi_->val_)
25  || boost::math::isnan(cvi_->val_))) {
26  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
27  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
28  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
29  } else {
30  avi_->adj_ += adj_ * bvi_->val_;
31  bvi_->adj_ += adj_ * avi_->val_;
32  cvi_->adj_ += adj_;
33  }
34  }
35  };
36 
37  class fma_vvd_vari : public op_vvd_vari {
38  public:
39  fma_vvd_vari(vari* avi, vari* bvi, double c) :
40  op_vvd_vari(::fma(avi->val_, bvi->val_, c),
41  avi, bvi, c) {
42  }
43  void chain() {
44  if (unlikely(boost::math::isnan(avi_->val_)
45  || boost::math::isnan(bvi_->val_)
46  || boost::math::isnan(cd_))) {
47  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
48  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
49  } else {
50  avi_->adj_ += adj_ * bvi_->val_;
51  bvi_->adj_ += adj_ * avi_->val_;
52  }
53  }
54  };
55 
56  class fma_vdv_vari : public op_vdv_vari {
57  public:
58  fma_vdv_vari(vari* avi, double b, vari* cvi) :
59  op_vdv_vari(::fma(avi->val_ , b, cvi->val_),
60  avi, b, cvi) {
61  }
62  void chain() {
63  if (unlikely(boost::math::isnan(avi_->val_)
64  || boost::math::isnan(cvi_->val_)
65  || boost::math::isnan(bd_))) {
66  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
67  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
68  } else {
69  avi_->adj_ += adj_ * bd_;
70  cvi_->adj_ += adj_;
71  }
72  }
73  };
74 
75  class fma_vdd_vari : public op_vdd_vari {
76  public:
77  fma_vdd_vari(vari* avi, double b, double c) :
78  op_vdd_vari(::fma(avi->val_ , b, c),
79  avi, b, c) {
80  }
81  void chain() {
82  if (unlikely(boost::math::isnan(avi_->val_)
83  || boost::math::isnan(bd_)
84  || boost::math::isnan(cd_)))
85  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
86  else
87  avi_->adj_ += adj_ * bd_;
88  }
89  };
90 
91  class fma_ddv_vari : public op_ddv_vari {
92  public:
93  fma_ddv_vari(double a, double b, vari* cvi) :
94  op_ddv_vari(::fma(a, b, cvi->val_),
95  a, b, cvi) {
96  }
97  void chain() {
98  if (unlikely(boost::math::isnan(cvi_->val_)
99  || boost::math::isnan(ad_)
100  || boost::math::isnan(bd_)))
101  cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
102  else
103  cvi_->adj_ += adj_;
104  }
105  };
106  }
107 
129  inline var fma(const stan::math::var& a,
130  const stan::math::var& b,
131  const stan::math::var& c) {
132  return var(new fma_vvv_vari(a.vi_, b.vi_, c.vi_));
133  }
134 
154  inline var fma(const stan::math::var& a,
155  const stan::math::var& b,
156  const double& c) {
157  return var(new fma_vvd_vari(a.vi_, b.vi_, c));
158  }
159 
179  inline var fma(const stan::math::var& a,
180  const double& b,
181  const stan::math::var& c) {
182  return var(new fma_vdv_vari(a.vi_, b, c.vi_));
183  }
184 
202  inline var fma(const stan::math::var& a,
203  const double& b,
204  const double& c) {
205  return var(new fma_vdd_vari(a.vi_, b, c));
206  }
207 
225  inline var fma(const double& a,
226  const stan::math::var& b,
227  const double& c) {
228  return var(new fma_vdd_vari(b.vi_, a, c));
229  }
230 
248  inline var fma(const double& a,
249  const double& b,
250  const stan::math::var& c) {
251  return var(new fma_ddv_vari(a, b, c.vi_));
252  }
253 
273  inline var fma(const double& a,
274  const stan::math::var& b,
275  const stan::math::var& c) {
276  return var(new fma_vdv_vari(b.vi_, a, c.vi_)); // a-b symmetry
277  }
278 
279  }
280 }
281 #endif
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:32
bool isnan(const stan::math::var &v)
Checks if the given number is NaN.
Definition: boost_isnan.hpp:22
#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:44

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