1 #ifndef __STAN__PROB__INTERNAL_MATH_HPP__
2 #define __STAN__PROB__INTERNAL_MATH_HPP__
5 #include <boost/math/special_functions/gamma.hpp>
6 #include <boost/math/special_functions/beta.hpp>
13 double F32(
double a,
double b,
double c,
double d,
double e,
double z)
25 for(
int k = 0; k < 500; ++k)
28 double p = (a + k) * (b + k) * (c + k) / ( (d + k) * (e + k) * (k + 1) );
48 void gradF32(
double* g,
double a,
double b,
double c,
double d,
double e,
double z)
53 for(
double *p = g; p != g + 6; ++p) *p = 0;
54 for(
double *p = gOld; p != gOld + 6; ++p) *p = 0;
63 for(
int k = 0; k < 500; ++k)
66 double C = (a + k) / (d + k);
67 C *= (b + k) / (e + k);
68 C *= (c + k) / (1 + k);
78 gOld[0] = tNew * (gOld[0] / tOld + 1.0 / (a + k) );
79 gOld[1] = tNew * (gOld[1] / tOld + 1.0 / (b + k) );
80 gOld[2] = tNew * (gOld[2] / tOld + 1.0 / (c + k) );
82 gOld[3] = tNew * (gOld[3] / tOld - 1.0 / (d + k) );
83 gOld[4] = tNew * (gOld[4] / tOld - 1.0 / (e + k) );
85 gOld[5] = tNew * ( gOld[5] / tOld + 1.0 / z );
87 for(
int i = 0; i < 6; ++i) g[i] += gOld[i];
96 void grad2F1(
double& gradA,
double& gradC,
double a,
double b,
double c,
double z,
double precision = 1
e-6)
107 double tNew = (a * b) / c;
109 while(
fabs(tNew) > precision)
112 gradAold = tNew * (gradAold / tOld + 1.0 / (a + k) );
113 gradCold = tNew * (gradCold / tOld - 1.0 / (c + k) );
120 tNew = ( (a + k) / (c + k) ) * ( (b + k) / (k + 1) ) * z * tOld;
132 void gradIncBeta(
double& g1,
double& g2,
double a,
double b,
double z)
137 double c3 = boost::math::beta(a, b, z);
139 double C =
std::exp( a * c1 + b * c2 ) / a;
144 grad2F1(dF1, dF2, a + b, 1, a + 1, z);
146 g1 = (c1 - 1.0 / a) * c3 + C * (dF1 + dF2);
147 g2 = c2 * c3 + C * dF1;
153 double digammaA,
double digammaB,
double digammaSum,
double betaAB)
161 double b1 = boost::math::beta(a, b, z);
163 g1 = ( dBda - b1 * (digammaA - digammaSum) ) / betaAB;
164 g2 = ( dBdb - b1 * (digammaB - digammaSum) ) / betaAB;
172 using boost::math::gamma_p;
179 double delta = s / (a * a);
181 while (
fabs(delta) > precision)
186 delta = s / ((k + a) * (k + a));
192 return gamma_p(a, z) * ( dig - l ) +
std::exp( a * l ) * S / g;