1 #ifndef __STAN__PROB__DISTRIBUTIONS__DOUBLE_EXPONENTIAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__DOUBLE_EXPONENTIAL_HPP__
4 #include <boost/random/uniform_01.hpp>
5 #include <boost/random/variate_generator.hpp>
18 inline int sign(
const T& z) {
19 return (z == 0) ? 0 : z < 0 ? -1 : 1;
24 template <
bool propto,
25 typename T_y,
typename T_loc,
typename T_scale,
30 static const char*
function
31 =
"stan::prob::double_exponential_log(%1%)";
50 if(!
check_finite(
function, y,
"Random variable", &logp, Policy()))
63 "Random variable",
"Location parameter",
"Shape parameter",
81 inv_sigma_squared(
length(sigma));
84 for (
size_t i = 0; i <
length(sigma); i++) {
85 const double sigma_dbl =
value_of(sigma_vec[i]);
87 inv_sigma[i] = 1.0 / sigma_dbl;
91 inv_sigma_squared[i] = inv_sigma[i] * inv_sigma[i];
95 for (
size_t n = 0; n < N; n++) {
96 const double y_dbl =
value_of(y_vec[n]);
97 const double mu_dbl =
value_of(mu_vec[n]);
100 const double y_m_mu = y_dbl - mu_dbl;
101 const double fabs_y_m_mu =
fabs(y_m_mu);
107 logp -= log_sigma[n];
109 logp -= fabs_y_m_mu * inv_sigma[n];
112 double sign_y_m_mu_times_inv_sigma(0);
114 sign_y_m_mu_times_inv_sigma =
sign(y_m_mu) * inv_sigma[n];
116 operands_and_partials.
d_x1[n] -= sign_y_m_mu_times_inv_sigma;
119 operands_and_partials.
d_x2[n] += sign_y_m_mu_times_inv_sigma;
122 operands_and_partials.
d_x3[n] += -inv_sigma[n] + fabs_y_m_mu * inv_sigma_squared[n];
124 return operands_and_partials.
to_var(logp);
128 template <
bool propto,
129 typename T_y,
typename T_loc,
typename T_scale>
132 const T_scale& sigma) {
133 return double_exponential_log<propto>(y,mu,sigma,
138 template <
typename T_y,
typename T_loc,
typename T_scale,
143 return double_exponential_log<false>(y,mu,sigma,Policy());
146 template <
typename T_y,
typename T_loc,
typename T_scale>
149 const T_scale& sigma) {
150 return double_exponential_log<false>(y,mu,sigma,
168 template <
typename T_y,
typename T_loc,
typename T_scale,
173 static const char*
function
174 =
"stan::prob::double_exponential_cdf(%1%)";
178 using boost::math::tools::promote_args;
180 typename promote_args<T_y,T_loc,T_scale>::type lp(0.0);
181 if(!
check_finite(
function, y,
"Random variable", &lp, Policy()))
194 return exp((y-mu)/sigma)/2;
196 return 1 -
exp((mu-y)/sigma)/2;
199 template <
typename T_y,
typename T_loc,
typename T_scale>
200 typename boost::math::tools::promote_args<T_y,T_loc,T_scale>::type
210 using boost::variate_generator;
211 using boost::random::uniform_01;
214 variate_generator<RNG&, uniform_01<> >
215 rng_unit_01(rng, uniform_01<>());
217 double laplaceRN = rng_unit_01();
218 if(0.5 - laplaceRN > 0)
220 else if(0.5 - laplaceRN < 0)
222 return mu - sigma * a *
log(1 - 2 *
abs(0.5 - laplaceRN));