var.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_CORE_VAR_HPP
2 #define STAN_MATH_REV_CORE_VAR_HPP
3 
7 #include <boost/math/tools/config.hpp>
8 #include <ostream>
9 #include <vector>
10 #include <complex>
11 #include <string>
12 #include <exception>
13 
14 namespace stan {
15 namespace math {
16 
17 // forward declare
18 static void grad(vari* vi);
19 
20 /**
21  * Independent (input) and dependent (output) variables for gradients.
22  *
23  * This class acts as a smart pointer, with resources managed by
24  * an agenda-based memory manager scoped to a single gradient
25  * calculation.
26  *
27  * An var is constructed with a double and used like any
28  * other scalar. Arithmetical functions like negation, addition,
29  * and subtraction, as well as a range of mathematical functions
30  * like exponentiation and powers are overridden to operate on
31  * var values objects.
32  */
33 class var {
34  public:
35  // FIXME: doc what this is for
36  typedef double Scalar;
37 
38  /**
39  * Pointer to the implementation of this variable.
40  *
41  * This value should not be modified, but may be accessed in
42  * <code>var</code> operators to construct <code>vari</code>
43  * instances.
44  */
46 
47  /**
48  * Return <code>true</code> if this variable has been
49  * declared, but not been defined. Any attempt to use an
50  * undefined variable's value or adjoint will result in a
51  * segmentation fault.
52  *
53  * @return <code>true</code> if this variable does not yet have
54  * a defined variable.
55  */
56  bool is_uninitialized() { return (vi_ == static_cast<vari*>(nullptr)); }
57 
58  /**
59  * Construct a variable for later assignment.
60  *
61  * This is implemented as a no-op, leaving the underlying implementation
62  * dangling. Before an assignment, the behavior is thus undefined just
63  * as for a basic double.
64  */
65  var() : vi_(static_cast<vari*>(0U)) {}
66 
67  /**
68  * Construct a variable from a pointer to a variable implementation.
69  *
70  * @param vi Variable implementation.
71  */
72  var(vari* vi) : vi_(vi) {} // NOLINT
73 
74  /**
75  * Construct a variable from the specified arithmetic argument
76  * by constructing a new <code>vari</code> with the argument
77  * cast to <code>double</code>, and a zero adjoint.
78  *
79  * @param x Value of the variable.
80  */
81  var(float x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
82 
83  /**
84  * Construct a variable from the specified arithmetic argument
85  * by constructing a new <code>vari</code> with the argument as
86  * a value and a zero adjoint.
87  *
88  * @param x Value of the variable.
89  */
90  var(double x) : vi_(new vari(x)) {} // NOLINT
91 
92  /**
93  * Construct a variable from the specified arithmetic argument
94  * by constructing a new <code>vari</code> with the argument
95  * cast to <code>double</code>, and a zero adjoint.
96  *
97  * @param x Value of the variable.
98  */
99  var(long double x) : vi_(new vari(x)) {} // NOLINT
100 
101  /**
102  * Construct a variable from the specified arithmetic argument
103  * by constructing a new <code>vari</code> with the argument
104  * cast to <code>double</code>, and a zero adjoint.
105  *
106  * @param x Value of the variable.
107  */
108  var(bool x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
109 
110  /**
111  * Construct a variable from the specified arithmetic argument
112  * by constructing a new <code>vari</code> with the argument
113  * cast to <code>double</code>, and a zero adjoint.
114  *
115  * @param x Value of the variable.
116  */
117  var(char x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
118 
119  /**
120  * Construct a variable from the specified arithmetic argument
121  * by constructing a new <code>vari</code> with the argument
122  * cast to <code>double</code>, and a zero adjoint.
123  *
124  * @param x Value of the variable.
125  */
126  var(short x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
127 
128  /**
129  * Construct a variable from the specified arithmetic argument
130  * by constructing a new <code>vari</code> with the argument
131  * cast to <code>double</code>, and a zero adjoint.
132  *
133  * @param x Value of the variable.
134  */
135  var(int x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
136 
137  /**
138  * Construct a variable from the specified arithmetic argument
139  * by constructing a new <code>vari</code> with the argument
140  * cast to <code>double</code>, and a zero adjoint.
141  *
142  * @param x Value of the variable.
143  */
144  var(long x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
145 
146  /**
147  * Construct a variable from the specified arithmetic argument
148  * by constructing a new <code>vari</code> with the argument
149  * cast to <code>double</code>, and a zero adjoint.
150  *
151  * @param x Value of the variable.
152  */
153  var(unsigned char x) // NOLINT(runtime/explicit)
154  : vi_(new vari(static_cast<double>(x))) {}
155 
156  /**
157  * Construct a variable from the specified arithmetic argument
158  * by constructing a new <code>vari</code> with the argument
159  * cast to <code>double</code>, and a zero adjoint.
160  *
161  * @param x Value of the variable.
162  */
163  // NOLINTNEXTLINE
164  var(unsigned short x) : vi_(new vari(static_cast<double>(x))) {}
165 
166  /**
167  * Construct a variable from the specified arithmetic argument
168  * by constructing a new <code>vari</code> with the argument
169  * cast to <code>double</code>, and a zero adjoint.
170  *
171  * @param x Value of the variable.
172  */
173  var(unsigned int x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
174 
175  /**
176  * Construct a variable from the specified arithmetic argument
177  * by constructing a new <code>vari</code> with the argument
178  * cast to <code>double</code>, and a zero adjoint.
179  *
180  * @param x Value of the variable.
181  */
182  // NOLINTNEXTLINE
183  var(unsigned long x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
184 
185  /**
186  * Construct a variable from the specified arithmetic argument
187  * by constructing a new <code>vari</code> with the argument
188  * cast to <code>double</code>, and a zero adjoint. Only works
189  * if the imaginary part is zero.
190  *
191  * @param x Value of the variable.
192  */
193  explicit var(const std::complex<double>& x) {
194  if (imag(x) == 0) {
195  vi_ = new vari(real(x));
196  } else {
197  std::stringstream ss;
198  ss << "Imaginary part of std::complex used to construct var"
199  << " must be zero. Found real part = " << real(x) << " and "
200  << " found imaginary part = " << imag(x) << std::endl;
201  std::string msg = ss.str();
202  throw std::invalid_argument(msg);
203  }
204  }
205 
206  /**
207  * Construct a variable from the specified arithmetic argument
208  * by constructing a new <code>vari</code> with the argument
209  * cast to <code>double</code>, and a zero adjoint. Only works
210  * if the imaginary part is zero.
211  *
212  * @param x Value of the variable.
213  */
214  explicit var(const std::complex<float>& x) {
215  if (imag(x) == 0) {
216  vi_ = new vari(static_cast<double>(real(x)));
217  } else {
218  std::stringstream ss;
219  ss << "Imaginary part of std::complex used to construct var"
220  << " must be zero. Found real part = " << real(x) << " and "
221  << " found imaginary part = " << imag(x) << std::endl;
222  std::string msg = ss.str();
223  throw std::invalid_argument(msg);
224  }
225  }
226 
227  /**
228  * Construct a variable from the specified arithmetic argument
229  * by constructing a new <code>vari</code> with the argument
230  * cast to <code>double</code>, and a zero adjoint. Only works
231  * if the imaginary part is zero.
232  *
233  * @param x Value of the variable.
234  */
235  explicit var(const std::complex<long double>& x) {
236  if (imag(x) == 0) {
237  vi_ = new vari(static_cast<double>(real(x)));
238  } else {
239  std::stringstream ss;
240  ss << "Imaginary part of std::complex used to construct var"
241  << " must be zero. Found real part = " << real(x) << " and "
242  << " found imaginary part = " << imag(x) << std::endl;
243  std::string msg = ss.str();
244  throw std::invalid_argument(msg);
245  }
246  }
247 
248 #ifdef _WIN64
249 
250  // these two ctors are for Win64 to enable 64-bit signed
251  // and unsigned integers, because long and unsigned long
252  // are still 32-bit
253 
254  /**
255  * Construct a variable from the specified arithmetic argument
256  * by constructing a new <code>vari</code> with the argument
257  * cast to <code>double</code>, and a zero adjoint.
258  *
259  * @param x Value of the variable.
260  */
261  var(size_t x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
262 
263  /**
264  * Construct a variable from the specified arithmetic argument
265  * by constructing a new <code>vari</code> with the argument
266  * cast to <code>double</code>, and a zero adjoint.
267  *
268  * @param x Value of the variable.
269  */
270  var(ptrdiff_t x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
271 #endif
272 
273 #ifdef BOOST_MATH_USE_FLOAT128
274 
275  // this ctor is for later GCCs that have the __float128
276  // type enabled, because it gets enabled by boost
277 
278  /**
279  * Construct a variable from the specified arithmetic argument
280  * by constructing a new <code>vari</code> with the argument
281  * cast to <code>double</code>, and a zero adjoint.
282  *
283  * @param x Value of the variable.
284  */
285  var(__float128 x) : vi_(new vari(static_cast<double>(x))) {} // NOLINT
286 
287 #endif
288 
289  /**
290  * Return the value of this variable.
291  *
292  * @return The value of this variable.
293  */
294  inline double val() const { return vi_->val_; }
295 
296  /**
297  * Return the derivative of the root expression with
298  * respect to this expression. This method only works
299  * after one of the <code>grad()</code> methods has been
300  * called.
301  *
302  * @return Adjoint for this variable.
303  */
304  inline double adj() const { return vi_->adj_; }
305 
306  /**
307  * Compute the gradient of this (dependent) variable with respect to
308  * the specified vector of (independent) variables, assigning the
309  * specified vector to the gradient.
310  *
311  * The grad() function does <i>not</i> recover memory. In Stan
312  * 2.4 and earlier, this function did recover memory.
313  *
314  * @param x Vector of independent variables.
315  * @param g Gradient vector of partial derivatives of this
316  * variable with respect to x.
317  */
318  void grad(std::vector<var>& x, std::vector<double>& g) {
319  stan::math::grad(vi_);
320  g.resize(x.size());
321  for (size_t i = 0; i < x.size(); ++i)
322  g[i] = x[i].vi_->adj_;
323  }
324 
325  /**
326  * Compute the gradient of this (dependent) variable with respect
327  * to all (independent) variables.
328  *
329  * The grad() function does <i>not</i> recover memory.
330  */
331  void grad() { stan::math::grad(vi_); }
332 
333  // POINTER OVERRIDES
334 
335  /**
336  * Return a reference to underlying implementation of this variable.
337  *
338  * If <code>x</code> is of type <code>var</code>, then applying
339  * this operator, <code>*x</code>, has the same behavior as
340  * <code>*(x.vi_)</code>.
341  *
342  * <i>Warning</i>: The returned reference does not track changes to
343  * this variable.
344  *
345  * @return variable
346  */
347  inline vari& operator*() { return *vi_; }
348 
349  /**
350  * Return a pointer to the underlying implementation of this variable.
351  *
352  * If <code>x</code> is of type <code>var</code>, then applying
353  * this operator, <code>x-&gt;</code>, behaves the same way as
354  * <code>x.vi_-&gt;</code>.
355  *
356  * <i>Warning</i>: The returned result does not track changes to
357  * this variable.
358  */
359  inline vari* operator->() { return vi_; }
360 
361  // COMPOUND ASSIGNMENT OPERATORS
362 
363  /**
364  * The compound add/assignment operator for variables (C++).
365  *
366  * If this variable is a and the argument is the variable b,
367  * then (a += b) behaves exactly the same way as (a = a + b),
368  * creating an intermediate variable representing (a + b).
369  *
370  * @param b The variable to add to this variable.
371  * @return The result of adding the specified variable to this variable.
372  */
373  inline var& operator+=(const var& b);
374 
375  /**
376  * The compound add/assignment operator for scalars (C++).
377  *
378  * If this variable is a and the argument is the scalar b, then
379  * (a += b) behaves exactly the same way as (a = a + b). Note
380  * that the result is an assignable lvalue.
381  *
382  * @param b The scalar to add to this variable.
383  * @return The result of adding the specified variable to this variable.
384  */
385  inline var& operator+=(double b);
386 
387  /**
388  * The compound subtract/assignment operator for variables (C++).
389  *
390  * If this variable is a and the argument is the variable b,
391  * then (a -= b) behaves exactly the same way as (a = a - b).
392  * Note that the result is an assignable lvalue.
393  *
394  * @param b The variable to subtract from this variable.
395  * @return The result of subtracting the specified variable from
396  * this variable.
397  */
398  inline var& operator-=(const var& b);
399 
400  /**
401  * The compound subtract/assignment operator for scalars (C++).
402  *
403  * If this variable is a and the argument is the scalar b, then
404  * (a -= b) behaves exactly the same way as (a = a - b). Note
405  * that the result is an assignable lvalue.
406  *
407  * @param b The scalar to subtract from this variable.
408  * @return The result of subtracting the specified variable from this
409  * variable.
410  */
411  inline var& operator-=(double b);
412 
413  /**
414  * The compound multiply/assignment operator for variables (C++).
415  *
416  * If this variable is a and the argument is the variable b,
417  * then (a *= b) behaves exactly the same way as (a = a * b).
418  * Note that the result is an assignable lvalue.
419  *
420  * @param b The variable to multiply this variable by.
421  * @return The result of multiplying this variable by the
422  * specified variable.
423  */
424  inline var& operator*=(const var& b);
425 
426  /**
427  * The compound multiply/assignment operator for scalars (C++).
428  *
429  * If this variable is a and the argument is the scalar b, then
430  * (a *= b) behaves exactly the same way as (a = a * b). Note
431  * that the result is an assignable lvalue.
432  *
433  * @param b The scalar to multiply this variable by.
434  * @return The result of multplying this variable by the specified
435  * variable.
436  */
437  inline var& operator*=(double b);
438 
439  /**
440  * The compound divide/assignment operator for variables (C++). If this
441  * variable is a and the argument is the variable b, then (a /= b)
442  * behaves exactly the same way as (a = a / b). Note that the
443  * result is an assignable lvalue.
444  *
445  * @param b The variable to divide this variable by.
446  * @return The result of dividing this variable by the
447  * specified variable.
448  */
449  inline var& operator/=(const var& b);
450 
451  /**
452  * The compound divide/assignment operator for scalars (C++).
453  *
454  * If this variable is a and the argument is the scalar b, then
455  * (a /= b) behaves exactly the same way as (a = a / b). Note
456  * that the result is an assignable lvalue.
457  *
458  * @param b The scalar to divide this variable by.
459  * @return The result of dividing this variable by the specified
460  * variable.
461  */
462  inline var& operator/=(double b);
463 
464  /**
465  * Write the value of this auto-dif variable and its adjoint to
466  * the specified output stream.
467  *
468  * @param os Output stream to which to write.
469  * @param v Variable to write.
470  * @return Reference to the specified output stream.
471  */
472  friend std::ostream& operator<<(std::ostream& os, const var& v) {
473  if (v.vi_ == nullptr)
474  return os << "uninitialized";
475  return os << v.val();
476  }
477 };
478 
479 } // namespace math
480 } // namespace stan
481 #endif
var & operator+=(const var &b)
var & operator*=(const var &b)
var(unsigned char x)
Definition: var.hpp:153
var(long x)
Definition: var.hpp:144
var & operator/=(const var &b)
var(unsigned long x)
Definition: var.hpp:183
Float_t ss
Definition: plot.C:24
var(const std::complex< float > &x)
Definition: var.hpp:214
var(vari *vi)
Definition: var.hpp:72
vari & operator*()
Definition: var.hpp:347
static void grad(vari *vi)
Definition: grad.hpp:30
var & operator-=(const var &b)
const double val_
Definition: vari.hpp:38
var(double x)
Definition: var.hpp:90
var(const std::complex< double > &x)
Definition: var.hpp:193
var(bool x)
Definition: var.hpp:108
var(char x)
Definition: var.hpp:117
bool is_uninitialized()
Definition: var.hpp:56
var(unsigned int x)
Definition: var.hpp:173
vari * vi_
Definition: var.hpp:45
void invalid_argument(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
var(float x)
Definition: var.hpp:81
void grad(std::vector< var > &x, std::vector< double > &g)
Definition: var.hpp:318
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
vari * operator->()
Definition: var.hpp:359
void grad()
Definition: var.hpp:331
var(long double x)
Definition: var.hpp:99
const hit & b
Definition: hits.cxx:21
var(int x)
Definition: var.hpp:135
double Scalar
Definition: var.hpp:36
double adj_
Definition: vari.hpp:44
double val() const
Definition: var.hpp:294
friend std::ostream & operator<<(std::ostream &os, const var &v)
Definition: var.hpp:472
double adj() const
Definition: var.hpp:304
var(unsigned short x)
Definition: var.hpp:164
var(short x)
Definition: var.hpp:126
var(const std::complex< long double > &x)
Definition: var.hpp:235