1 #ifndef STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__BETA_HPP
2 #define STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__BETA_HPP
4 #include <boost/math/special_functions/gamma.hpp>
5 #include <boost/random/gamma_distribution.hpp>
6 #include <boost/random/variate_generator.hpp>
43 template <
bool propto,
44 typename T_y,
typename T_scale_succ,
typename T_scale_fail>
45 typename return_type<T_y,T_scale_succ,T_scale_fail>::type
47 const T_scale_succ& alpha,
const T_scale_fail& beta) {
48 static const char*
function =
"stan::prob::beta_log(%1%)";
79 "Random variable",
"First shape parameter",
80 "Second shape parameter",
94 for (
size_t n = 0; n < N; n++) {
95 const double y_dbl =
value_of(y_vec[n]);
96 if (y_dbl < 0 || y_dbl > 1)
102 operands_and_partials(y, alpha, beta);
109 for (
size_t n = 0; n <
length(y); n++) {
120 for (
size_t n = 0; n <
length(alpha); n++) {
132 for (
size_t n = 0; n <
length(beta); n++) {
142 lgamma_alpha_beta(
max_size(alpha,beta));
148 digamma_alpha_beta(
max_size(alpha,beta));
150 for (
size_t n = 0; n <
max_size(alpha,beta); n++) {
151 const double alpha_beta =
value_of(alpha_vec[n])
154 lgamma_alpha_beta[n] =
lgamma(alpha_beta);
157 digamma_alpha_beta[n] =
digamma(alpha_beta);
160 for (
size_t n = 0; n < N; n++) {
162 const double y_dbl =
value_of(y_vec[n]);
163 const double alpha_dbl =
value_of(alpha_vec[n]);
164 const double beta_dbl =
value_of(beta_vec[n]);
168 logp += lgamma_alpha_beta[n];
170 logp -= lgamma_alpha[n];
172 logp -= lgamma_beta[n];
174 logp += (alpha_dbl-1.0) * log_y[n];
176 logp += (beta_dbl-1.0) * log1m_y[n];
180 operands_and_partials.
d_x1[n] += (alpha_dbl-1)/y_dbl
181 + (beta_dbl-1)/(y_dbl-1);
183 operands_and_partials.
d_x2[n]
184 += log_y[n] + digamma_alpha_beta[n] - digamma_alpha[n];
186 operands_and_partials.
d_x3[n]
187 += log1m_y[n] + digamma_alpha_beta[n] - digamma_beta[n];
189 return operands_and_partials.
to_var(logp);
192 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
195 const T_scale_fail& beta) {
196 return beta_log<false>(y,alpha,beta);
211 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
214 const T_scale_fail& beta) {
222 static const char*
function =
"stan::prob::beta_cdf(%1%)";
226 using boost::math::tools::promote_args;
238 "Random variable",
"Shape parameter",
239 "Scale Parameter", &P);
247 size_t N =
max_size(y, alpha, beta);
250 operands_and_partials(y, alpha, beta);
256 return operands_and_partials.
to_var(0.0);
261 using boost::math::ibeta_derivative;
268 digamma_alpha_vec(
max_size(alpha, beta));
273 digamma_beta_vec(
max_size(alpha, beta));
278 digamma_sum_vec(
max_size(alpha, beta));
283 betafunc_vec(
max_size(alpha, beta));
288 for (
size_t i = 0; i < N; i++) {
290 const double alpha_dbl =
value_of(alpha_vec[i]);
291 const double beta_dbl =
value_of(beta_vec[i]);
293 digamma_alpha_vec[i] =
digamma(alpha_dbl);
294 digamma_beta_vec[i] =
digamma(beta_dbl);
295 digamma_sum_vec[i] =
digamma(alpha_dbl + beta_dbl);
296 betafunc_vec[i] = boost::math::beta(alpha_dbl, beta_dbl);
303 for (
size_t n = 0; n < N; n++) {
307 if (
value_of(y_vec[n]) >= 1.0)
continue;
310 const double y_dbl =
value_of(y_vec[n]);
311 const double alpha_dbl =
value_of(alpha_vec[n]);
312 const double beta_dbl =
value_of(beta_vec[n]);
315 const double Pn =
ibeta(alpha_dbl, beta_dbl, y_dbl);
320 operands_and_partials.
d_x1[n] += ibeta_derivative(alpha_dbl, beta_dbl,
329 digamma_alpha_vec[n],
330 digamma_beta_vec[n], digamma_sum_vec[n],
335 operands_and_partials.
d_x2[n] += g1 / Pn;
337 operands_and_partials.
d_x3[n] += g2 / Pn;
342 operands_and_partials.
d_x1[n] *= P;
346 operands_and_partials.
d_x2[n] *= P;
350 operands_and_partials.
d_x3[n] *= P;
353 return operands_and_partials.
to_var(P);
356 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
359 const T_scale_fail& beta) {
367 static const char*
function =
"stan::prob::beta_cdf(%1%)";
373 using boost::math::tools::promote_args;
385 "Random variable",
"Shape parameter",
386 "Scale Parameter", &cdf_log);
392 size_t N =
max_size(y, alpha, beta);
395 operands_and_partials(y, alpha, beta);
399 using boost::math::ibeta_derivative;
406 digamma_alpha_vec(
max_size(alpha, beta));
411 digamma_beta_vec(
max_size(alpha, beta));
416 digamma_sum_vec(
max_size(alpha, beta));
421 betafunc_vec(
max_size(alpha, beta));
426 for (
size_t i = 0; i < N; i++) {
428 const double alpha_dbl =
value_of(alpha_vec[i]);
429 const double beta_dbl =
value_of(beta_vec[i]);
431 digamma_alpha_vec[i] =
digamma(alpha_dbl);
432 digamma_beta_vec[i] =
digamma(beta_dbl);
433 digamma_sum_vec[i] =
digamma(alpha_dbl + beta_dbl);
434 betafunc_vec[i] = boost::math::beta(alpha_dbl, beta_dbl);
439 for (
size_t n = 0; n < N; n++) {
442 const double y_dbl =
value_of(y_vec[n]);
443 const double alpha_dbl =
value_of(alpha_vec[n]);
444 const double beta_dbl =
value_of(beta_vec[n]);
447 const double Pn =
ibeta(alpha_dbl, beta_dbl, y_dbl);
452 operands_and_partials.
d_x1[n] +=
453 ibeta_derivative(alpha_dbl, beta_dbl, y_dbl) / Pn;
461 digamma_alpha_vec[n],
462 digamma_beta_vec[n], digamma_sum_vec[n],
466 operands_and_partials.
d_x2[n] += g1 / Pn;
468 operands_and_partials.
d_x3[n] += g2 / Pn;
471 return operands_and_partials.
to_var(cdf_log);
474 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
477 const T_scale_fail& beta) {
485 static const char*
function =
"stan::prob::beta_cdf(%1%)";
491 using boost::math::tools::promote_args;
495 double ccdf_log(0.0);
505 "Random variable",
"Shape parameter",
506 "Scale Parameter", &ccdf_log);
512 size_t N =
max_size(y, alpha, beta);
515 operands_and_partials(y, alpha, beta);
519 using boost::math::ibeta_derivative;
526 digamma_alpha_vec(
max_size(alpha, beta));
530 digamma_beta_vec(
max_size(alpha, beta));
534 digamma_sum_vec(
max_size(alpha, beta));
538 betafunc_vec(
max_size(alpha, beta));
543 for (
size_t i = 0; i < N; i++) {
545 const double alpha_dbl =
value_of(alpha_vec[i]);
546 const double beta_dbl =
value_of(beta_vec[i]);
548 digamma_alpha_vec[i] =
digamma(alpha_dbl);
549 digamma_beta_vec[i] =
digamma(beta_dbl);
550 digamma_sum_vec[i] =
digamma(alpha_dbl + beta_dbl);
551 betafunc_vec[i] = boost::math::beta(alpha_dbl, beta_dbl);
556 for (
size_t n = 0; n < N; n++) {
559 const double y_dbl =
value_of(y_vec[n]);
560 const double alpha_dbl =
value_of(alpha_vec[n]);
561 const double beta_dbl =
value_of(beta_vec[n]);
564 const double Pn = 1.0 -
ibeta(alpha_dbl, beta_dbl, y_dbl);
569 operands_and_partials.
d_x1[n] -=
570 ibeta_derivative(alpha_dbl, beta_dbl, y_dbl) / Pn;
578 digamma_alpha_vec[n],
579 digamma_beta_vec[n], digamma_sum_vec[n],
583 operands_and_partials.
d_x2[n] -= g1 / Pn;
585 operands_and_partials.
d_x3[n] -= g2 / Pn;
588 return operands_and_partials.
to_var(ccdf_log);
596 using boost::variate_generator;
597 using boost::random::gamma_distribution;
599 static const char*
function =
"stan::prob::beta_rng(%1%)";
608 variate_generator<RNG&, gamma_distribution<> >
609 rng_gamma_alpha(rng, gamma_distribution<>(alpha, 1.0));
610 variate_generator<RNG&, gamma_distribution<> >
611 rng_gamma_beta(rng, gamma_distribution<>(beta, 1.0));
612 double a = rng_gamma_alpha();
613 double b = rng_gamma_beta();
fvar< T > log1m(const fvar< T > &x)
return_type< T_y, T_scale_succ, T_scale_fail >::type beta_cdf(const T_y &y, const T_scale_succ &alpha, const T_scale_fail &beta)
Calculates the beta cumulative distribution function for the given variate and scale variables...
void gradRegIncBeta(double &g1, double &g2, double a, double b, double z, double digammaA, double digammaB, double digammaSum, double betaAB)
return_type< T_y, T_scale_succ, T_scale_fail >::type beta_cdf_log(const T_y &y, const T_scale_succ &alpha, const T_scale_fail &beta)
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(const T_a a, const T_b b)
Calculated the value of the first argument times log of the second argument while behaving properly w...
return_type< T_y, T_scale_succ, T_scale_fail >::type beta_log(const T_y &y, const T_scale_succ &alpha, const T_scale_fail &beta)
The log of the beta density for the specified scalar(s) given the specified sample size(s)...
DoubleVectorView allocates double values to be used as intermediate values.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
fvar< T > lgamma(const fvar< T > &x)
A variable implementation that stores operands and derivatives with respect to the variable...
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
VectorView< double *, is_vector< T2 >::value, is_constant_struct< T2 >::value > d_x2
var ibeta(const var &a, const var &b, const var &x)
The normalized incomplete beta function of a, b, and x.
bool check_nonnegative(const char *function, const T_y &y, const char *name, T_result *result)
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result)
size_t max_size(const T1 &x1, const T2 &x2)
double beta_rng(const double alpha, const double beta, RNG &rng)
bool check_less_or_equal(const char *function, const T_y &y, const T_high &high, const char *name, T_result *result)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
fvar< T > digamma(const fvar< T > &x)
return_type< T_y, T_scale_succ, T_scale_fail >::type beta_ccdf_log(const T_y &y, const T_scale_succ &alpha, const T_scale_fail &beta)
VectorView< double *, is_vector< T1 >::value, is_constant_struct< T1 >::value > d_x1
VectorView< double *, is_vector< T3 >::value, is_constant_struct< T3 >::value > d_x3
fvar< T > log(const fvar< T > &x)
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
boost::math::tools::promote_args< T >::type log1m(T x)
Return the natural logarithm of one minus the specified value.