vari.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_CORE_VARI_HPP
2 #define STAN_MATH_REV_CORE_VARI_HPP
3 
6 #include <ostream>
7 
8 namespace stan {
9 namespace math {
10 
11 // forward declaration of var
12 class var;
13 
14 /**
15  * The variable implementation base class.
16  *
17  * This class is complete (not abstract) and may be used for
18  * constants.
19  *
20  * A variable implementation is constructed with a constant
21  * value. It also stores the adjoint for storing the partial
22  * derivative with respect to the root of the derivative tree.
23  *
24  * The chain() method applies the chain rule. Concrete extensions
25  * of this class will represent base variables or the result
26  * of operations such as addition or subtraction. These extended
27  * classes will store operand variables and propagate derivative
28  * information via an implementation of chain().
29  */
30 class vari {
31  private:
32  friend class var;
33 
34  public:
35  /**
36  * The value of this variable.
37  */
38  const double val_;
39 
40  /**
41  * The adjoint of this variable, which is the partial derivative
42  * of this variable with respect to the root variable.
43  */
44  double adj_;
45 
46  /**
47  * Construct a variable implementation from a value. The
48  * adjoint is initialized to zero.
49  *
50  * All constructed variables are added to the stack. Variables
51  * should be constructed before variables on which they depend
52  * to insure proper partial derivative propagation. During
53  * derivative propagation, the chain() method of each variable
54  * will be called in the reverse order of construction.
55  *
56  * @param x Value of the constructed variable.
57  */
58  explicit vari(double x) : val_(x), adj_(0.0) {
59  ChainableStack::instance().var_stack_.push_back(this);
60  }
61 
62  vari(double x, bool stacked) : val_(x), adj_(0.0) {
63  if (stacked)
64  ChainableStack::instance().var_stack_.push_back(this);
65  else
67  }
68 
69  /**
70  * Throw an illegal argument exception.
71  *
72  * <i>Warning</i>: Destructors should never called for var objects.
73  *
74  * @throw Logic exception always.
75  */
76  virtual ~vari() {
77  // this will never get called
78  }
79 
80  /**
81  * Apply the chain rule to this variable based on the variables
82  * on which it depends. The base implementation in this class
83  * is a no-op.
84  */
85  virtual void chain() {}
86 
87  /**
88  * Initialize the adjoint for this (dependent) variable to 1.
89  * This operation is applied to the dependent variable before
90  * propagating derivatives, setting the derivative of the
91  * result with respect to itself to be 1.
92  */
93  void init_dependent() { adj_ = 1.0; }
94 
95  /**
96  * Set the adjoint value of this variable to 0. This is used to
97  * reset adjoints before propagating derivatives again (for
98  * example in a Jacobian calculation).
99  */
100  void set_zero_adjoint() { adj_ = 0.0; }
101 
102  /**
103  * Insertion operator for vari. Prints the current value and
104  * the adjoint value.
105  *
106  * @param os [in, out] ostream to modify
107  * @param v [in] vari object to print.
108  *
109  * @return The modified ostream.
110  */
111  friend std::ostream& operator<<(std::ostream& os, const vari* v) {
112  return os << v->val_ << ":" << v->adj_;
113  }
114 
115  /**
116  * Allocate memory from the underlying memory pool. This memory is
117  * is managed as a whole externally.
118  *
119  * Warning: Classes should not be allocated with this operator
120  * if they have non-trivial destructors.
121  *
122  * @param nbytes Number of bytes to allocate.
123  * @return Pointer to allocated bytes.
124  */
125  static inline void* operator new(size_t nbytes) {
127  }
128 
129  /**
130  * Delete a pointer from the underlying memory pool.
131  *
132  * This no-op implementation enables a subclass to throw
133  * exceptions in its constructor. An exception thrown in the
134  * constructor of a subclass will result in an error being
135  * raised, which is in turn caught and calls delete().
136  *
137  * See the discussion of "plugging the memory leak" in:
138  * http://www.parashift.com/c++-faq/memory-pools.html
139  */
140  static inline void operator delete(void* /* ignore arg */) { /* no op */
141  }
142 };
143 
144 } // namespace math
145 } // namespace stan
146 #endif
virtual void chain()
Definition: vari.hpp:85
friend std::ostream & operator<<(std::ostream &os, const vari *v)
Definition: vari.hpp:111
virtual ~vari()
Definition: vari.hpp:76
const double val_
Definition: vari.hpp:38
void set_zero_adjoint()
Definition: vari.hpp:100
Long64_t nbytes
vari(double x)
Definition: vari.hpp:58
static AutodiffStackStorage & instance()
void init_dependent()
Definition: vari.hpp:93
double adj_
Definition: vari.hpp:44
void * alloc(size_t len)
vari(double x, bool stacked)
Definition: vari.hpp:62