1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__BERNOULLI_HPP__
4 #include <boost/random/bernoulli_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
21 template <
bool propto,
22 typename T_n,
typename T_prob,
24 typename return_type<T_prob>::type
28 static const char*
function =
"stan::prob::bernoulli_log(%1%)";
48 if (!
check_finite(
function, theta,
"Probability parameter", &logp, Policy()))
51 "Probability parameter", &logp, Policy()))
55 "Random variable",
"Probability parameter",
71 for (
size_t n = 0; n < N; n++) {
74 const double theta_dbl =
value_of(theta_vec[0]);
77 logp += N *
log(theta_dbl);
78 operands_and_partials.
d_x1[0] += N / theta_dbl;
79 }
else if (sum == 0) {
80 logp += N *
log1m(theta_dbl);
81 operands_and_partials.
d_x1[0] += N / (theta_dbl - 1);
83 const double log_theta =
log(theta_dbl);
84 const double log1m_theta =
log1m(theta_dbl);
86 logp += sum * log_theta;
87 logp += (N -
sum) * log1m_theta;
89 operands_and_partials.
d_x1[0] += sum / theta_dbl;
90 operands_and_partials.
d_x1[0] += (N -
sum) / (theta_dbl - 1);
94 for (
size_t n = 0; n < N; n++) {
96 const int n_int =
value_of(n_vec[n]);
97 const double theta_dbl =
value_of(theta_vec[n]);
101 logp +=
log(theta_dbl);
103 logp +=
log1m(theta_dbl);
109 operands_and_partials.
d_x1[n] += 1.0 / theta_dbl;
111 operands_and_partials.
d_x1[n] += 1.0 / (theta_dbl - 1);
115 return operands_and_partials.
to_var(logp);
118 template <
bool propto,
124 const T_prob& theta) {
128 template <
typename T_y,
136 return bernoulli_log<false>(n,theta,Policy());
139 template <
typename T_y,
typename T_prob>
143 const T_prob& theta) {
150 template <
bool propto,
158 static const char*
function =
"stan::prob::bernoulli_logit_log(%1%)";
180 if (!
check_not_nan(
function, theta,
"Logit transformed probability parameter",
185 "Random variable",
"Probability parameter",
199 for (
size_t n = 0; n < N; n++) {
201 const int n_int =
value_of(n_vec[n]);
202 const double theta_dbl =
value_of(theta_vec[n]);
205 const int sign = 2*n_int-1;
206 const double ntheta = sign * theta_dbl;
207 const double exp_m_ntheta =
exp(-ntheta);
211 const static double cutoff = 20.0;
213 logp -= exp_m_ntheta;
214 else if (ntheta < -cutoff)
217 logp -=
log1p(exp_m_ntheta);
222 const static double cutoff = 20.0;
224 operands_and_partials.
d_x1[n] -= exp_m_ntheta;
225 else if (ntheta < -cutoff)
226 operands_and_partials.
d_x1[n] +=
sign;
228 operands_and_partials.
d_x1[n] += sign * exp_m_ntheta / (exp_m_ntheta + 1);
231 return operands_and_partials.
to_var(logp);
235 template <
bool propto,
241 const T_prob& theta) {
246 template <
typename T_n,
254 return bernoulli_logit_log<false>(n,theta,Policy());
258 template <
typename T_n,
263 const T_prob& theta) {
268 template <
bool propto,
typename T_n,
typename T_prob,
class Policy>
271 static const char*
function =
"stan::prob::bernoulli_cdf(%1%)";
285 if (!
check_finite(
function, theta,
"Probability parameter", &P, Policy()))
289 "Probability parameter", &P, Policy()))
294 "Random variable",
"Probability parameter",
313 + operands_and_partials.
nvaris, 0.0);
319 return operands_and_partials.
to_var(0.0);
322 for (
size_t i = 0; i <
size; i++) {
326 if (
value_of(n_vec[i]) >= 1)
continue;
328 const double Pi = 1 -
value_of(theta_vec[i]);
333 operands_and_partials.
d_x1[i] += - 1 / Pi;
339 for(
size_t i = 0; i <
stan::length(theta); ++i) operands_and_partials.
d_x1[i] *= P;
341 return operands_and_partials.
to_var(P);
344 template <
bool propto,
typename T_n,
typename T_prob>
350 template <
typename T_n,
typename T_prob,
class Policy>
353 return bernoulli_cdf<false>(n, theta, Policy());
356 template <
typename T_n,
typename T_prob>
366 using boost::variate_generator;
367 using boost::bernoulli_distribution;
368 variate_generator<RNG&, bernoulli_distribution<> >