| Stan Math Library 2.12.0 reverse mode automatic differentiation

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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>
6 #include <stan/math/prim/scal/fun/constants.hpp>
7 #include <stan/math/prim/scal/fun/is_nan.hpp>
8 #include <stan/math/prim/scal/meta/likely.hpp>
9 #include <valarray>
10 #include <limits>
11
12 #ifdef _MSC_VER
13 template<typename T>
14 T fma(T x, T y, T z) {
15 return x*y+z;
16 }
17 #endif
18
19 namespace stan {
20 namespace math {
21
22 namespace {
23 class fma_vvv_vari : public op_vvv_vari {
24 public:
25 fma_vvv_vari(vari* avi, vari* bvi, vari* cvi) :
26 op_vvv_vari(::fma(avi->val_, bvi->val_, cvi->val_),
27 avi, bvi, cvi) {
28 }
29 void chain() {
30 if (unlikely(is_nan(avi_->val_)
31 || is_nan(bvi_->val_)
32 || is_nan(cvi_->val_))) {
33 avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
34 bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
35 cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
36 } else {
37 avi_->adj_ += adj_ * bvi_->val_;
38 bvi_->adj_ += adj_ * avi_->val_;
39 cvi_->adj_ += adj_;
40 }
41 }
42 };
43
44 class fma_vvd_vari : public op_vvd_vari {
45 public:
46 fma_vvd_vari(vari* avi, vari* bvi, double c) :
47 op_vvd_vari(::fma(avi->val_, bvi->val_, c),
48 avi, bvi, c) {
49 }
50 void chain() {
51 if (unlikely(is_nan(avi_->val_)
52 || is_nan(bvi_->val_)
53 || is_nan(cd_))) {
54 avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
55 bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
56 } else {
57 avi_->adj_ += adj_ * bvi_->val_;
58 bvi_->adj_ += adj_ * avi_->val_;
59 }
60 }
61 };
62
63 class fma_vdv_vari : public op_vdv_vari {
64 public:
65 fma_vdv_vari(vari* avi, double b, vari* cvi) :
66 op_vdv_vari(::fma(avi->val_ , b, cvi->val_),
67 avi, b, cvi) {
68 }
69 void chain() {
70 if (unlikely(is_nan(avi_->val_)
71 || is_nan(cvi_->val_)
72 || is_nan(bd_))) {
73 avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
74 cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
75 } else {
76 avi_->adj_ += adj_ * bd_;
77 cvi_->adj_ += adj_;
78 }
79 }
80 };
81
82 class fma_vdd_vari : public op_vdd_vari {
83 public:
84 fma_vdd_vari(vari* avi, double b, double c) :
85 op_vdd_vari(::fma(avi->val_ , b, c),
86 avi, b, c) {
87 }
88 void chain() {
89 if (unlikely(is_nan(avi_->val_)
90 || is_nan(bd_)
91 || is_nan(cd_)))
92 avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
93 else
94 avi_->adj_ += adj_ * bd_;
95 }
96 };
97
98 class fma_ddv_vari : public op_ddv_vari {
99 public:
100 fma_ddv_vari(double a, double b, vari* cvi) :
101 op_ddv_vari(::fma(a, b, cvi->val_),
102 a, b, cvi) {
103 }
104 void chain() {
105 if (unlikely(is_nan(cvi_->val_)
106 || is_nan(ad_)
107 || is_nan(bd_)))
108 cvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
109 else
110 cvi_->adj_ += adj_;
111 }
112 };
113 }
114
136 inline var fma(const var& a,
137 const var& b,
138 const var& c) {
139 return var(new fma_vvv_vari(a.vi_, b.vi_, c.vi_));
140 }
141
161 inline var fma(const var& a,
162 const var& b,
163 double c) {
164 return var(new fma_vvd_vari(a.vi_, b.vi_, c));
165 }
166
186 inline var fma(const var& a,
187 double b,
188 const var& c) {
189 return var(new fma_vdv_vari(a.vi_, b, c.vi_));
190 }
191
209 inline var fma(const var& a,
210 double b,
211 double c) {
212 return var(new fma_vdd_vari(a.vi_, b, c));
213 }
214
232 inline var fma(double a,
233 const var& b,
234 double c) {
235 return var(new fma_vdd_vari(b.vi_, a, c));
236 }
237
255 inline var fma(double a,
256 double b,
257 const var& c) {
258 return var(new fma_ddv_vari(a, b, c.vi_));
259 }
260
280 inline var fma(double a,
281 const var& b,
282 const var& c) {
283 return var(new fma_vdv_vari(b.vi_, a, c.vi_)); // a-b symmetry
284 }
285
286 }
287 }
288 #endif
core.hpp
is_nan.hpp
stan
Definition: log_sum_exp.hpp:8
stan::math::var
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:30
unlikely
#define unlikely(x)
Definition: likely.hpp:9
stan::math::fma
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
stan::math::var::vi_
vari * vi_
Pointer to the implementation of this variable.
Definition: var.hpp:42
stan::math::fma
var fma(double a, const var &b, const var &c)
The fused multiply-add function for a value and two variables (C99).
Definition: fma.hpp:280
likely.hpp
constants.hpp
stan::math::is_nan
int is_nan(const fvar< T > &x)
Returns 1 if the input's value is NaN and 0 otherwise.
Definition: is_nan.hpp:21

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