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>
23 template <
bool propto,
typename T_n,
typename T_prob>
24 typename return_type<T_prob>::type
26 const T_prob& theta) {
27 static const char*
function =
"stan::prob::bernoulli_log(%1%)";
46 check_finite(
function, theta,
"Probability parameter", &logp);
48 "Probability parameter", &logp);
51 "Random variable",
"Probability parameter",
66 for (
size_t n = 0; n < N; n++) {
69 const double theta_dbl =
value_of(theta_vec[0]);
72 logp += N *
log(theta_dbl);
74 operands_and_partials.
d_x1[0] += N / theta_dbl;
75 }
else if (sum == 0) {
76 logp += N *
log1m(theta_dbl);
78 operands_and_partials.
d_x1[0] += N / (theta_dbl - 1);
80 const double log_theta =
log(theta_dbl);
81 const double log1m_theta =
log1m(theta_dbl);
83 logp += sum * log_theta;
84 logp += (N -
sum) * log1m_theta;
88 operands_and_partials.
d_x1[0] += sum / theta_dbl;
89 operands_and_partials.
d_x1[0] += (N -
sum) / (theta_dbl - 1);
93 for (
size_t n = 0; n < N; n++) {
95 const int n_int =
value_of(n_vec[n]);
96 const double theta_dbl =
value_of(theta_vec[n]);
99 logp +=
log(theta_dbl);
101 logp +=
log1m(theta_dbl);
106 operands_and_partials.
d_x1[n] += 1.0 / theta_dbl;
108 operands_and_partials.
d_x1[n] += 1.0 / (theta_dbl - 1);
112 return operands_and_partials.
to_var(logp);
115 template <
typename T_y,
typename T_prob>
119 const T_prob& theta) {
120 return bernoulli_log<false>(n,theta);
126 template <
bool propto,
typename T_n,
typename T_prob>
129 static const char*
function =
"stan::prob::bernoulli_logit_log(%1%)";
150 check_not_nan(
function, theta,
"Logit transformed probability parameter",
154 "Random variable",
"Probability parameter",
167 for (
size_t n = 0; n < N; n++) {
169 const int n_int =
value_of(n_vec[n]);
170 const double theta_dbl =
value_of(theta_vec[n]);
173 const int sign = 2*n_int-1;
174 const double ntheta = sign * theta_dbl;
175 const double exp_m_ntheta =
exp(-ntheta);
178 const static double cutoff = 20.0;
180 logp -= exp_m_ntheta;
181 else if (ntheta < -cutoff)
184 logp -=
log1p(exp_m_ntheta);
188 const static double cutoff = 20.0;
190 operands_and_partials.
d_x1[n] -= exp_m_ntheta;
191 else if (ntheta < -cutoff)
192 operands_and_partials.
d_x1[n] +=
sign;
194 operands_and_partials.
d_x1[n] += sign * exp_m_ntheta / (exp_m_ntheta + 1);
197 return operands_and_partials.
to_var(logp);
200 template <
typename T_n,
205 const T_prob& theta) {
206 return bernoulli_logit_log<false>(n,theta);
210 template <
typename T_n,
typename T_prob>
213 static const char*
function =
"stan::prob::bernoulli_cdf(%1%)";
227 check_finite(
function, theta,
"Probability parameter", &P);
229 "Probability parameter", &P);
232 "Random variable",
"Probability parameter",
248 return operands_and_partials.
to_var(0.0);
251 for (
size_t i = 0; i <
size; i++) {
255 if (
value_of(n_vec[i]) >= 1)
continue;
257 const double Pi = 1 -
value_of(theta_vec[i]);
262 operands_and_partials.
d_x1[i] += - 1 / Pi;
267 for(
size_t i = 0; i <
stan::length(theta); ++i) operands_and_partials.
d_x1[i] *= P;
269 return operands_and_partials.
to_var(P);
272 template <
typename T_n,
typename T_prob>
275 static const char*
function =
"stan::prob::bernoulli_cdf_log(%1%)";
289 check_finite(
function, theta,
"Probability parameter", &P);
291 "Probability parameter", &P);
294 "Random variable",
"Probability parameter",
313 for (
size_t i = 0; i <
size; i++) {
317 if (
value_of(n_vec[i]) >= 1)
continue;
319 const double Pi = 1 -
value_of(theta_vec[i]);
324 operands_and_partials.
d_x1[i] -= 1 / Pi;
328 return operands_and_partials.
to_var(P);
331 template <
typename T_n,
typename T_prob>
334 static const char*
function =
"stan::prob::bernoulli_ccdf_log(%1%)";
348 check_finite(
function, theta,
"Probability parameter", &P);
350 "Probability parameter", &P);
353 "Random variable",
"Probability parameter",
369 return operands_and_partials.
to_var(0.0);
372 for (
size_t i = 0; i <
size; i++) {
379 const double Pi =
value_of(theta_vec[i]);
384 operands_and_partials.
d_x1[i] += 1 / Pi;
388 return operands_and_partials.
to_var(P);
396 using boost::variate_generator;
397 using boost::bernoulli_distribution;
399 static const char*
function =
"stan::prob::bernoulli_rng(%1%)";
404 check_finite(
function, theta,
"Probability parameter", (
double*)0);
406 "Probability parameter", (
double*)0);
408 variate_generator<RNG&, bernoulli_distribution<> >
fvar< T > log1m(const fvar< T > &x)
bool check_bounded(const char *function, const T_y &y, const T_low &low, const T_high &high, const char *name, T_result *result)
boost::math::tools::promote_args< T >::type log1p(const T x)
Return the natural logarithm of one plus the specified value.
T_return_type to_var(double logp)
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is finite.
boost::math::tools::promote_args< T >::type inv_logit(const T a)
Returns the inverse logit function applied to the argument.
return_type< T_prob >::type bernoulli_ccdf_log(const T_n &n, const T_prob &theta)
int bernoulli_rng(const double theta, RNG &rng)
T value_of(const fvar< T > &v)
Return the value of the specified variable.
fvar< T > sum(const Eigen::Matrix< fvar< T >, R, C > &m)
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...
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)
return_type< T_prob >::type bernoulli_log(const T_n &n, const T_prob &theta)
return_type< T_prob >::type bernoulli_cdf_log(const T_n &n, const T_prob &theta)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
int size(const std::vector< T > &x)
return_type< T_prob >::type bernoulli_cdf(const T_n &n, const T_prob &theta)
VectorView< double *, is_vector< T1 >::value, is_constant_struct< T1 >::value > d_x1
fvar< T > log(const fvar< T > &x)
return_type< T_prob >::type bernoulli_logit_log(const T_n &n, const T_prob &theta)
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
fvar< T > exp(const fvar< T > &x)
fvar< T > log1p(const fvar< T > &x)
boost::math::tools::promote_args< T >::type log1m(T x)
Return the natural logarithm of one minus the specified value.
double negative_infinity()
Return negative infinity.