33
44#include < stan/math/prim/meta.hpp>
55#include < stan/math/prim/fun/beta.hpp>
6- #include < stan/math/prim/fun/grad_inc_beta.hpp>
76#include < stan/math/prim/fun/inc_beta.hpp>
87#include < cmath>
98
@@ -16,6 +15,9 @@ namespace math {
1615 * <code>ibeta(a, b, z)</code>, with respect to the arguments
1716 * <code>a</code> and <code>b</code>.
1817 *
18+ * Uses the equivalence to a hypergeometric function. See
19+ * http://dlmf.nist.gov/8.17#ii
20+ *
1921 * @tparam T type of arguments
2022 * @param[out] g1 partial derivative of <code>ibeta(a, b, z)</code>
2123 * 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,
3436 const T& digammaA, const T& digammaB,
3537 const T& digammaSum, const T& betaAB) {
3638 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;
4358}
4459
4560} // namespace math
0 commit comments