Automatic Differentiation
 
Loading...
Searching...
No Matches
gamma_p.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_FUN_GAMMA_P_HPP
2#define STAN_MATH_REV_FUN_GAMMA_P_HPP
3
11#include <cmath>
12
13namespace stan {
14namespace math {
15
16namespace internal {
18 public:
20 : op_vv_vari(gamma_p(avi->val_, bvi->val_), avi, bvi) {}
21 void chain() {
22 using std::exp;
23 using std::fabs;
24 using std::log;
25
26 if (is_inf(avi_->val_)) {
27 avi_->adj_ = NOT_A_NUMBER;
28 bvi_->adj_ = NOT_A_NUMBER;
29 return;
30 }
31 if (is_inf(bvi_->val_)) {
32 avi_->adj_ = NOT_A_NUMBER;
33 bvi_->adj_ = NOT_A_NUMBER;
34 return;
35 }
36
37 // return zero derivative as gamma_p is flat
38 // to machine precision for b / a > 10
39 if (std::fabs(bvi_->val_ / avi_->val_) > 10) {
40 return;
41 }
42
43 avi_->adj_ += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bvi_->val_);
44 bvi_->adj_
45 += adj_
46 * std::exp(-bvi_->val_ + (avi_->val_ - 1.0) * std::log(bvi_->val_)
47 - lgamma(avi_->val_));
48 }
49};
50
52 public:
53 gamma_p_vd_vari(vari* avi, double b)
54 : op_vd_vari(gamma_p(avi->val_, b), avi, b) {}
55 void chain() {
56 if (is_inf(avi_->val_)) {
57 avi_->adj_ = NOT_A_NUMBER;
58 return;
59 }
60 if (is_inf(bd_)) {
61 avi_->adj_ = NOT_A_NUMBER;
62 return;
63 }
64
65 // return zero derivative as gamma_p is flat
66 // to machine precision for b / a > 10
67 if (std::fabs(bd_ / avi_->val_) > 10) {
68 return;
69 }
70
71 avi_->adj_ += adj_ * grad_reg_lower_inc_gamma(avi_->val_, bd_);
72 }
73};
74
76 public:
77 gamma_p_dv_vari(double a, vari* bvi)
78 : op_dv_vari(gamma_p(a, bvi->val_), a, bvi) {}
79 void chain() {
80 if (is_inf(ad_)) {
81 bvi_->adj_ = NOT_A_NUMBER;
82 return;
83 }
84 if (is_inf(bvi_->val_)) {
85 bvi_->adj_ = NOT_A_NUMBER;
86 return;
87 }
88
89 // return zero derivative as gamma_p is flat to
90 // machine precision for b / a > 10
91 if (std::fabs(bvi_->val_ / ad_) > 10) {
92 return;
93 }
94
95 bvi_->adj_ += adj_
96 * std::exp(-bvi_->val_ + (ad_ - 1.0) * std::log(bvi_->val_)
97 - lgamma(ad_));
98 }
99};
100} // namespace internal
101
102inline var gamma_p(const var& a, const var& b) {
103 return var(new internal::gamma_p_vv_vari(a.vi_, b.vi_));
104}
105
106inline var gamma_p(const var& a, double b) {
107 return var(new internal::gamma_p_vd_vari(a.vi_, b));
108}
109
110inline var gamma_p(double a, const var& b) {
111 return var(new internal::gamma_p_dv_vari(a, b.vi_));
112}
113
114} // namespace math
115} // namespace stan
116#endif
gamma_p_dv_vari(double a, vari *bvi)
Definition gamma_p.hpp:77
gamma_p_vd_vari(vari *avi, double b)
Definition gamma_p.hpp:53
gamma_p_vv_vari(vari *avi, vari *bvi)
Definition gamma_p.hpp:19
static constexpr double NOT_A_NUMBER
(Quiet) not-a-number value.
Definition constants.hpp:56
fvar< T > lgamma(const fvar< T > &x)
Return the natural logarithm of the gamma function applied to the specified argument.
Definition lgamma.hpp:21
fvar< T > gamma_p(const fvar< T > &x1, const fvar< T > &x2)
Definition gamma_p.hpp:18
var_value< double > var
Definition var.hpp:1187
int is_inf(const fvar< T > &x)
Returns 1 if the input's value is infinite and 0 otherwise.
Definition is_inf.hpp:21
return_type_t< T1, T2 > grad_reg_lower_inc_gamma(const T1 &a, const T2 &z, double precision=1e-10, int max_steps=1e5)
Computes the gradient of the lower regularized incomplete gamma function.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...