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>
42 template <
bool propto,
43 typename T_y,
typename T_scale_succ,
typename T_scale_fail,
45 typename return_type<T_y,T_scale_succ,T_scale_fail>::type
46 beta_log(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta,
48 static const char*
function =
"stan::prob::beta_log(%1%)";
50 using boost::math::digamma;
74 "First shape parameter",
78 "First shape parameter",
82 "Second shape parameter",
86 "Second shape parameter",
89 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
93 "Random variable",
"First shape parameter",
94 "Second shape parameter",
105 size_t N =
max_size(y, alpha, beta);
107 for (
size_t n = 0; n < N; n++) {
108 const double y_dbl =
value_of(y_vec[n]);
109 if (y_dbl < 0 || y_dbl > 1)
115 operands_and_partials(y, alpha, beta);
122 for (
size_t n = 0; n <
length(y); n++) {
133 for (
size_t n = 0; n <
length(alpha); n++) {
137 digamma_alpha[n] = digamma(
value_of(alpha_vec[n]));
145 for (
size_t n = 0; n <
length(beta); n++) {
149 digamma_beta[n] = digamma(
value_of(beta_vec[n]));
155 lgamma_alpha_beta(
max_size(alpha,beta));
161 digamma_alpha_beta(
max_size(alpha,beta));
163 for (
size_t n = 0; n <
max_size(alpha,beta); n++) {
166 lgamma_alpha_beta[n] =
lgamma(alpha_beta);
169 digamma_alpha_beta[n] = digamma(alpha_beta);
172 for (
size_t n = 0; n < N; n++) {
174 const double y_dbl =
value_of(y_vec[n]);
175 const double alpha_dbl =
value_of(alpha_vec[n]);
176 const double beta_dbl =
value_of(beta_vec[n]);
180 logp += lgamma_alpha_beta[n];
182 logp -= lgamma_alpha[n];
184 logp -= lgamma_beta[n];
186 logp += (alpha_dbl-1.0) * log_y[n];
188 logp += (beta_dbl-1.0) * log1m_y[n];
192 operands_and_partials.
d_x1[n] += (alpha_dbl-1)/y_dbl + (beta_dbl-1)/(y_dbl-1);
194 operands_and_partials.
d_x2[n]
195 += log_y[n] + digamma_alpha_beta[n] - digamma_alpha[n];
197 operands_and_partials.
d_x3[n]
198 += log1m_y[n] + digamma_alpha_beta[n] - digamma_beta[n];
200 return operands_and_partials.
to_var(logp);
203 template <
bool propto,
204 typename T_y,
typename T_scale_succ,
typename T_scale_fail>
207 beta_log(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta) {
211 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail,
214 beta_log(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta,
216 return beta_log<false>(y,alpha,beta,Policy());
219 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
222 beta_log(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta) {
240 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail,
class Policy>
242 beta_cdf(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta,
249 static const char*
function =
"stan::prob::beta_cdf(%1%)";
254 using boost::math::tools::promote_args;
260 if (!
check_finite(
function, alpha,
"First shape parameter", &P, Policy()))
263 if (!
check_positive(
function, alpha,
"First shape parameter", &P, Policy()))
266 if (!
check_finite(
function, beta,
"Second shape parameter", &P, Policy()))
269 if (!
check_positive(
function, beta,
"Second shape parameter", &P, Policy()))
272 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
276 "Random variable",
"Shape parameter",
"Scale Parameter",
284 size_t N =
max_size(y, alpha, beta);
287 operands_and_partials(y, alpha, beta);
296 return operands_and_partials.
to_var(0.0);
301 using boost::math::ibeta_derivative;
302 using boost::math::digamma;
308 digamma_alpha_vec(
max_size(alpha, beta));
313 digamma_beta_vec(
max_size(alpha, beta));
318 digamma_sum_vec(
max_size(alpha, beta));
323 betafunc_vec(
max_size(alpha, beta));
328 for (
size_t i = 0; i < N; i++) {
330 const double alpha_dbl =
value_of(alpha_vec[i]);
331 const double beta_dbl =
value_of(beta_vec[i]);
333 digamma_alpha_vec[i] = digamma(alpha_dbl);
334 digamma_beta_vec[i] = digamma(beta_dbl);
335 digamma_sum_vec[i] = digamma(alpha_dbl + beta_dbl);
336 betafunc_vec[i] = boost::math::beta(alpha_dbl, beta_dbl);
343 for (
size_t n = 0; n < N; n++) {
347 if (
value_of(y_vec[n]) >= 1.0)
continue;
350 const double y_dbl =
value_of(y_vec[n]);
351 const double alpha_dbl =
value_of(alpha_vec[n]);
352 const double beta_dbl =
value_of(beta_vec[n]);
355 const double Pn =
ibeta(alpha_dbl, beta_dbl, y_dbl);
360 operands_and_partials.
d_x1[n] += ibeta_derivative(alpha_dbl, beta_dbl, y_dbl) / Pn;
368 digamma_alpha_vec[n],
369 digamma_beta_vec[n], digamma_sum_vec[n],
374 operands_and_partials.
d_x2[n] += g1 / Pn;
377 operands_and_partials.
d_x3[n] += g2 / Pn;
381 for(
size_t n = 0; n <
stan::length(y); ++n) operands_and_partials.
d_x1[n] *= P;
385 for(
size_t n = 0; n <
stan::length(alpha); ++n) operands_and_partials.
d_x2[n] *= P;
389 for(
size_t n = 0; n <
stan::length(beta); ++n) operands_and_partials.
d_x3[n] *= P;
392 return operands_and_partials.
to_var(P);
395 template <
typename T_y,
typename T_scale_succ,
typename T_scale_fail>
397 beta_cdf(
const T_y& y,
const T_scale_succ& alpha,
const T_scale_fail& beta) {
406 using boost::variate_generator;
407 using boost::random::gamma_distribution;
408 variate_generator<RNG&, gamma_distribution<> >
409 rng_gamma_alpha(rng, gamma_distribution<>(alpha, 1.0));
410 variate_generator<RNG&, gamma_distribution<> >
411 rng_gamma_beta(rng, gamma_distribution<>(beta, 1.0));
412 double a = rng_gamma_alpha();
413 double b = rng_gamma_beta();