fvar.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_FWD_CORE_FVAR_HPP
2 #define STAN_MATH_FWD_CORE_FVAR_HPP
3 
7 #include <boost/utility/enable_if.hpp>
8 #include <ostream>
9 
10 namespace stan {
11 namespace math {
12 
13 /**
14  * This template class represents scalars used in forward-mode
15  * automatic differentiation, which consist of values and
16  * directional derivatives of the specified template type. When
17  * performing operations on instances of this class, all operands
18  * should be either primitive integer or double values or dual
19  * numbers representing derivatives in the same direction. The
20  * typical use case is to have a unit length directional
21  * derivative in the direction of a single independent variable.
22  *
23  * By using reverse-mode automatic derivative variables,
24  * second-order derivatives may
25  * be calculated. By using fvar&lt;<var&gt; instances,
26  * third-order derivatives may be calculated. These are called
27  * mixed-mode automatic differentiation variable in Stan.
28  *
29  * Specialized functionals that perform differentiation on
30  * functors may be found in the matrix subdirectories of the
31  * reverse, forward, and mixed-mode directories.
32  *
33  * The <a
34  * href="https://en.wikipedia.org/wiki/Automatic_differentiation">Wikipedia
35  * page on automatic differentiation</a> describes how
36  * forward-mode automatic differentiation works mathematically in
37  * terms of dual numbers.
38  *
39  * @tparam T type of value and tangent
40  */
41 template <typename T>
42 struct fvar {
43  /**
44  * The value of this variable.
45  */
47 
48  /**
49  * The tangent (derivative) of this variable.
50  */
51  T d_;
52 
53  /**
54  * Return the value of this variable.
55  *
56  * @return value of this variable
57  */
58  T val() const { return val_; }
59 
60  /**
61  * Return the tangent (derivative) of this variable.
62  *
63  * @return tangent of this variable
64  */
65  T tangent() const { return d_; }
66 
67  /**
68  * Construct a forward variable with zero value and tangent.
69  */
70  fvar() : val_(0.0), d_(0.0) {}
71 
72  /**
73  * Construct a forward variable with value and tangent set to
74  * the value and tangent of the specified variable.
75  *
76  * @param[in] x variable to be copied
77  */
78  fvar(const fvar<T>& x) : val_(x.val_), d_(x.d_) {}
79 
80  /**
81  * Construct a forward variable with the specified value and
82  * zero tangent.
83  *
84  * @tparam V type of value (must be assignable to the value and
85  * tangent type T)
86  * @param[in] v value
87  */
88  fvar(const T& v) : val_(v), d_(0.0) { // NOLINT(runtime/explicit)
89  if (unlikely(is_nan(v)))
90  d_ = v;
91  }
92 
93  /**
94  * Construct a forward variable with the specified value and
95  * zero tangent.
96  *
97  * @tparam V type of value (must be assignable to the value and
98  * tangent type T)
99  * @param[in] v value
100  * @param[in] dummy value given by default with enable-if
101  * metaprogramming
102  */
103  template <typename V>
104  fvar(const V& v,
105  typename boost::enable_if_c<ad_promotable<V, T>::value>::type* dummy = 0)
106  : val_(v), d_(0.0) {
107  if (unlikely(is_nan(v)))
108  d_ = v;
109  }
110 
111  /**
112  * Construct a forward variable with the specified value and
113  * tangent.
114  *
115  * @tparam V type of value (must be assignable to the value and
116  * tangent type T)
117  * @tparam D type of tangent (must be assignable to the value and
118  * tangent type T)
119  * @param[in] v value
120  * @param[in] d tangent
121  */
122  template <typename V, typename D>
123  fvar(const V& v, const D& d) : val_(v), d_(d) {
124  if (unlikely(is_nan(v)))
125  d_ = v;
126  }
127 
128  /**
129  * Add the specified variable to this variable and return a
130  * reference to this variable.
131  *
132  * @param[in] x2 variable to add
133  * @return reference to this variable after addition
134  */
135  inline fvar<T>& operator+=(const fvar<T>& x2) {
136  val_ += x2.val_;
137  d_ += x2.d_;
138  return *this;
139  }
140 
141  /**
142  * Add the specified value to this variable and return a
143  * reference to this variable.
144  *
145  * @param[in] x2 value to add
146  * @return reference to this variable after addition
147  */
148  inline fvar<T>& operator+=(double x2) {
149  val_ += x2;
150  return *this;
151  }
152 
153  /**
154  * Subtract the specified variable from this variable and return a
155  * reference to this variable.
156  *
157  * @param[in] x2 variable to subtract
158  * @return reference to this variable after subtraction
159  */
160  inline fvar<T>& operator-=(const fvar<T>& x2) {
161  val_ -= x2.val_;
162  d_ -= x2.d_;
163  return *this;
164  }
165 
166  /**
167  * Subtract the specified value from this variable and return a
168  * reference to this variable.
169  *
170  * @param[in] x2 value to add
171  * @return reference to this variable after subtraction
172  */
173  inline fvar<T>& operator-=(double x2) {
174  val_ -= x2;
175  return *this;
176  }
177 
178  /**
179  * Multiply this variable by the the specified variable and
180  * return a reference to this variable.
181  *
182  * @param[in] x2 variable to multiply
183  * @return reference to this variable after multiplication
184  */
185  inline fvar<T>& operator*=(const fvar<T>& x2) {
186  d_ = d_ * x2.val_ + val_ * x2.d_;
187  val_ *= x2.val_;
188  return *this;
189  }
190 
191  /**
192  * Multiply this variable by the the specified value and
193  * return a reference to this variable.
194  *
195  * @param[in] x2 value to multiply
196  * @return reference to this variable after multiplication
197  */
198  inline fvar<T>& operator*=(double x2) {
199  val_ *= x2;
200  d_ *= x2;
201  return *this;
202  }
203 
204  /**
205  * Divide this variable by the the specified variable and
206  * return a reference to this variable.
207  *
208  * @param[in] x2 variable to divide this variable by
209  * @return reference to this variable after division
210  */
211  inline fvar<T>& operator/=(const fvar<T>& x2) {
212  d_ = (d_ * x2.val_ - val_ * x2.d_) / (x2.val_ * x2.val_);
213  val_ /= x2.val_;
214  return *this;
215  }
216 
217  /**
218  * Divide this value by the the specified variable and
219  * return a reference to this variable.
220  *
221  * @param[in] x2 value to divide this variable by
222  * @return reference to this variable after division
223  */
224  inline fvar<T>& operator/=(double x2) {
225  val_ /= x2;
226  d_ /= x2;
227  return *this;
228  }
229 
230  /**
231  * Increment this variable by one and return a reference to this
232  * variable after the increment.
233  *
234  * @return reference to this variable after increment
235  */
236  inline fvar<T>& operator++() {
237  ++val_;
238  return *this;
239  }
240 
241  /**
242  * Increment this variable by one and return a reference to a
243  * copy of this variable before it was incremented.
244  *
245  * @return reference to copy of this variable before increment
246  */
247  inline fvar<T> operator++(int /*dummy*/) {
248  fvar<T> result(val_, d_);
249  ++val_;
250  return result;
251  }
252 
253  /**
254  * Decrement this variable by one and return a reference to this
255  * variable after the decrement.
256  *
257  * @return reference to this variable after decrement
258  */
259  inline fvar<T>& operator--() {
260  --val_;
261  return *this;
262  }
263 
264  /**
265  * Decrement this variable by one and return a reference to a
266  * copy of this variable before it was decremented.
267  *
268  * @return reference to copy of this variable before decrement
269  */
270  inline fvar<T> operator--(int /*dummy*/) {
271  fvar<T> result(val_, d_);
272  --val_;
273  return result;
274  }
275 
276  /**
277  * Write the value of the specified variable to the specified
278  * output stream, returning a reference to the output stream.
279  *
280  * @param[in,out] os stream for writing value
281  * @param[in] v variable whose value is written
282  * @return reference to the specified output stream
283  */
284  friend std::ostream& operator<<(std::ostream& os, const fvar<T>& v) {
285  return os << v.val_;
286  }
287 };
288 } // namespace math
289 } // namespace stan
290 #endif
fvar< T > & operator-=(const fvar< T > &x2)
Definition: fvar.hpp:160
fvar< T > & operator/=(double x2)
Definition: fvar.hpp:224
fvar(const V &v, const D &d)
Definition: fvar.hpp:123
T tangent() const
Definition: fvar.hpp:65
fvar< T > operator--(int)
Definition: fvar.hpp:270
fvar(const fvar< T > &x)
Definition: fvar.hpp:78
fvar< T > & operator+=(const fvar< T > &x2)
Definition: fvar.hpp:135
fvar< T > & operator++()
Definition: fvar.hpp:236
Float_t d
Definition: plot.C:236
fvar< T > & operator--()
Definition: fvar.hpp:259
fvar< T > operator++(int)
Definition: fvar.hpp:247
#define unlikely(expr)
Definition: lz4.cxx:121
fvar< T > & operator-=(double x2)
Definition: fvar.hpp:173
T val() const
Definition: fvar.hpp:58
fvar< T > & operator+=(double x2)
Definition: fvar.hpp:148
fvar(const T &v)
Definition: fvar.hpp:88
fvar(const V &v, typename boost::enable_if_c< ad_promotable< V, T >::value >::type *dummy=0)
Definition: fvar.hpp:104
fvar< T > & operator*=(const fvar< T > &x2)
Definition: fvar.hpp:185
double T
Definition: Xdiff_gwt.C:5
int is_nan(const fvar< T > &x)
Definition: is_nan.hpp:19
fvar< T > & operator*=(double x2)
Definition: fvar.hpp:198
fvar< T > & operator/=(const fvar< T > &x2)
Definition: fvar.hpp:211