2
2
#define STAN_MATH_PRIM_FUN_GRAD_REG_INC_BETA_HPP
3
3
4
4
#include < stan/math/prim/meta.hpp>
5
- #include < stan/math/prim/fun/beta.hpp>
6
- #include < stan/math/prim/fun/grad_inc_beta.hpp>
7
5
#include < stan/math/prim/fun/inc_beta.hpp>
6
+ #include < stan/math/prim/fun/grad_2F1.hpp>
8
7
#include < cmath>
9
8
10
9
namespace stan {
@@ -16,6 +15,9 @@ namespace math {
16
15
* <code>ibeta(a, b, z)</code>, with respect to the arguments
17
16
* <code>a</code> and <code>b</code>.
18
17
*
18
+ * Uses the equivalence to a hypergeometric function. See
19
+ * http://dlmf.nist.gov/8.17#ii
20
+ *
19
21
* @tparam T type of arguments
20
22
* @param[out] g1 partial derivative of <code>ibeta(a, b, z)</code>
21
23
* with respect to <code>a</code>
@@ -34,12 +36,25 @@ void grad_reg_inc_beta(T& g1, T& g2, const T& a, const T& b, const T& z,
34
36
const T& digammaA, const T& digammaB,
35
37
const T& digammaSum, const T& betaAB) {
36
38
using std::exp ;
37
- T dBda = 0 ;
38
- T dBdb = 0 ;
39
- grad_inc_beta (dBda, dBdb, a, b, z);
40
- T b1 = beta (a, b) * inc_beta (a, b, z);
41
- g1 = (dBda - b1 * (digammaA - digammaSum)) / betaAB;
42
- g2 = (dBdb - b1 * (digammaB - digammaSum)) / betaAB;
39
+
40
+ T c1 = log (z);
41
+ T c2 = log1m (z);
42
+ T c3 = betaAB * inc_beta (a, b, z);
43
+ T C = exp (a * c1 + b * c2) / a;
44
+ T dF1 = 0 ;
45
+ T dF2 = 0 ;
46
+ T dF3 = 0 ;
47
+ T dFz = 0 ;
48
+ if (value_of_rec (C)) {
49
+ std::forward_as_tuple (dF1, dF2, dF3, dFz)
50
+ = grad_2F1<true >(a + b, 1.0 , a + 1 , z);
51
+ }
52
+
53
+ T dBda = (c1 - 1.0 / a) * c3 + C * (dF1 + dF3);
54
+ T dBdb = c2 * c3 + C * dF1;
55
+
56
+ g1 = (dBda - c3 * (digammaA - digammaSum)) / betaAB;
57
+ g2 = (dBdb - c3 * (digammaB - digammaSum)) / betaAB;
43
58
}
44
59
45
60
} // namespace math
0 commit comments