Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pow.hpp
Go to the documentation of this file.
1 #ifndef STAN__AGRAD__REV__FUNCTIONS__POW_HPP
2 #define STAN__AGRAD__REV__FUNCTIONS__POW_HPP
3 
4 #include <cmath>
5 #include <stan/agrad/rev/var.hpp>
11 #include <boost/math/special_functions/fpclassify.hpp>
12 
13 namespace stan {
14  namespace agrad {
15 
16  namespace {
17  class pow_vv_vari : public op_vv_vari {
18  public:
19  pow_vv_vari(vari* avi, vari* bvi) :
20  op_vv_vari(std::pow(avi->val_,bvi->val_),avi,bvi) {
21  }
22  void chain() {
23  if (unlikely(boost::math::isnan(avi_->val_)
24  || boost::math::isnan(bvi_->val_))) {
25  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
26  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
27  } else {
28  if (avi_->val_ == 0.0) return; // partials zero, avoids 0 & log(0)
29  avi_->adj_ += adj_ * bvi_->val_ * val_ / avi_->val_;
30  bvi_->adj_ += adj_ * std::log(avi_->val_) * val_;
31  }
32  }
33  };
34 
35  class pow_vd_vari : public op_vd_vari {
36  public:
37  pow_vd_vari(vari* avi, double b) :
38  op_vd_vari(std::pow(avi->val_,b),avi,b) {
39  }
40  void chain() {
41  if (unlikely(boost::math::isnan(avi_->val_)
42  || boost::math::isnan(bd_)))
43  avi_->adj_ = std::numeric_limits<double>::quiet_NaN();
44  else {
45  if (avi_->val_ == 0.0) return; // partials zero, avoids 0 & log(0)
46  avi_->adj_ += adj_ * bd_ * val_ / avi_->val_;
47  }
48  }
49  };
50 
51  class pow_dv_vari : public op_dv_vari {
52  public:
53  pow_dv_vari(double a, vari* bvi) :
54  op_dv_vari(std::pow(a,bvi->val_),a,bvi) {
55  }
56  void chain() {
57  if (unlikely(boost::math::isnan(bvi_->val_)
58  || boost::math::isnan(ad_)))
59  bvi_->adj_ = std::numeric_limits<double>::quiet_NaN();
60  else {
61  if (ad_ == 0.0) return; // partials zero, avoids 0 & log(0)
62  bvi_->adj_ += adj_ * std::log(ad_) * val_;
63  }
64  }
65  };
66  }
67 
106  inline var pow(const var& base, const var& exponent) {
107  return var(new pow_vv_vari(base.vi_,exponent.vi_));
108  }
109 
122  inline var pow(const var& base, const double exponent) {
123  if (exponent == 0.5)
124  return sqrt(base);
125  if (exponent == 1.0)
126  return base;
127  if (exponent == 2.0)
128  return base * base; // FIXME: square() functionality from special_functions
129  return var(new pow_vd_vari(base.vi_,exponent));
130  }
131 
144  inline var pow(const double base, const var& exponent) {
145  return var(new pow_dv_vari(base,exponent.vi_));
146  }
147 
148  }
149 }
150 #endif
bool isnan(const stan::agrad::var &v)
Checks if the given number is NaN.
fvar< T > pow(const fvar< T > &x1, const fvar< T > &x2)
Definition: pow.hpp:17
vari * vi_
Pointer to the implementation of this variable.
Definition: var.hpp:40
#define unlikely(x)
Definition: likely.hpp:9
fvar< T > sqrt(const fvar< T > &x)
Definition: sqrt.hpp:15
Independent (input) and dependent (output) variables for gradients.
Definition: var.hpp:27
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:15

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