1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__LOGISTIC_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__LOGISTIC_HPP__
4 #include <boost/random/exponential_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
19 template <
bool propto,
20 typename T_y,
typename T_loc,
typename T_scale,
22 typename return_type<T_y,T_loc,T_scale>::type
25 static const char*
function =
"stan::prob::logistic_log(%1%)";
44 if (!
check_finite(
function, y,
"Random variable", &logp, Policy()))
49 if (!
check_finite(
function, sigma,
"Scale parameter", &logp,
57 "Random variable",
"Location parameter",
"Scale parameter",
76 for (
size_t i = 0; i <
length(sigma); i++) {
77 inv_sigma[i] = 1.0 /
value_of(sigma_vec[i]);
83 exp_mu_div_sigma(
max_size(mu,sigma));
87 for (
size_t n = 0; n <
max_size(mu,sigma); n++)
89 for (
size_t n = 0; n <
max_size(y,sigma); n++)
94 for (
size_t n = 0; n < N; n++) {
95 const double y_dbl =
value_of(y_vec[n]);
96 const double mu_dbl =
value_of(mu_vec[n]);
98 const double y_minus_mu = y_dbl - mu_dbl;
99 const double y_minus_mu_div_sigma = y_minus_mu * inv_sigma[n];
100 double exp_m_y_minus_mu_div_sigma(0);
102 exp_m_y_minus_mu_div_sigma =
exp(-y_minus_mu_div_sigma);
103 double inv_1p_exp_y_minus_mu_div_sigma(0);
105 inv_1p_exp_y_minus_mu_div_sigma = 1 / (1 +
exp(y_minus_mu_div_sigma));
108 logp -= y_minus_mu_div_sigma;
110 logp -= log_sigma[n];
112 logp -= 2.0 *
log1p(exp_m_y_minus_mu_div_sigma);
115 operands_and_partials.
d_x1[n] += (2 * inv_1p_exp_y_minus_mu_div_sigma - 1) * inv_sigma[n];
117 operands_and_partials.
d_x2[n] +=
118 (1 - 2 * exp_mu_div_sigma[n] / (exp_mu_div_sigma[n] + exp_y_div_sigma[n])) * inv_sigma[n];
120 operands_and_partials.
d_x3[n] +=
121 ((1 - 2 * inv_1p_exp_y_minus_mu_div_sigma)*y_minus_mu*inv_sigma[n] - 1) * inv_sigma[n];
123 return operands_and_partials.
to_var(logp);
126 template <
bool propto,
127 typename T_y,
typename T_loc,
typename T_scale>
134 template <
typename T_y,
typename T_loc,
typename T_scale,
140 return logistic_log<false>(y,mu,sigma,Policy());
143 template <
typename T_y,
typename T_loc,
typename T_scale>
151 template <
typename T_y,
typename T_loc,
typename T_scale,
class Policy>
153 logistic_cdf(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const Policy&) {
159 static const char*
function =
"stan::prob::logistic_cdf(%1%)";
167 using boost::math::tools::promote_args;
171 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
174 if (!
check_finite(
function, mu,
"Location parameter", &P, Policy()))
177 if (!
check_finite(
function, sigma,
"Scale parameter", &P, Policy()))
180 if (!
check_positive(
function, sigma,
"Scale parameter", &P, Policy()))
184 "Random variable",
"Location parameter",
"Scale parameter",
203 if (
value_of(y_vec[i]) == -std::numeric_limits<double>::infinity())
204 return operands_and_partials.
to_var(0.0);
208 for (
size_t n = 0; n < N; n++) {
212 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
217 const double y_dbl =
value_of(y_vec[n]);
218 const double mu_dbl =
value_of(mu_vec[n]);
219 const double sigma_dbl =
value_of(sigma_vec[n]);
220 const double sigma_inv_vec = 1.0 /
value_of(sigma_vec[n]);
223 const double Pn = 1.0 / ( 1.0 +
exp( - (y_dbl - mu_dbl) * sigma_inv_vec ) );
228 operands_and_partials.
d_x1[n]
232 operands_and_partials.
d_x2[n]
236 operands_and_partials.
d_x3[n]
237 += - (y_dbl - mu_dbl) * sigma_inv_vec *
exp(
logistic_log(y_dbl, mu_dbl, sigma_dbl)) / Pn;
242 for(
size_t n = 0; n <
stan::length(y); ++n) operands_and_partials.
d_x1[n] *= P;
246 for(
size_t n = 0; n <
stan::length(mu); ++n) operands_and_partials.
d_x2[n] *= P;
250 for(
size_t n = 0; n <
stan::length(sigma); ++n) operands_and_partials.
d_x3[n] *= P;
253 return operands_and_partials.
to_var(P);
257 template <
typename T_y,
typename T_loc,
typename T_scale>
268 using boost::variate_generator;
269 using boost::random::exponential_distribution;
270 variate_generator<RNG&, exponential_distribution<> >
271 exp_rng(rng, exponential_distribution<>(1));
272 return mu - sigma *
std::log(exp_rng() / exp_rng());