1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__EXP__MOD__NORMAL__HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__EXP__MOD__NORMAL__HPP__
4 #include <boost/random/normal_distribution.hpp>
5 #include <boost/math/special_functions/fpclassify.hpp>
6 #include <boost/random/variate_generator.hpp>
21 template <
bool propto,
22 typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale,
class Policy>
23 typename return_type<T_y,T_loc,T_scale, T_inv_scale>::type
25 const T_inv_scale& lambda,
const Policy& ) {
26 static const char*
function =
"stan::prob::exp_mod_normal_log(%1%)";
47 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
52 if (!
check_finite(
function, lambda,
"Inv_scale parameter",
63 "Random variable",
"Location parameter",
"Scale parameter",
"Inv_scale paramter",
78 size_t N =
max_size(y, mu, sigma, lambda);
80 for (
size_t n = 0; n < N; n++) {
82 const double y_dbl =
value_of(y_vec[n]);
83 const double mu_dbl =
value_of(mu_vec[n]);
84 const double sigma_dbl =
value_of(sigma_vec[n]);
85 const double lambda_dbl =
value_of(lambda_vec[n]);
87 const double pi_dbl = boost::math::constants::pi<double>();
93 logp +=
log(lambda_dbl);
95 logp += lambda_dbl * (mu_dbl + 0.5 * lambda_dbl * sigma_dbl * sigma_dbl - y_dbl) +
log(
boost::math::erfc((mu_dbl + lambda_dbl * sigma_dbl * sigma_dbl - y_dbl) / (
std::sqrt(2.0) * sigma_dbl)));
98 const double deriv_logerfc = -2.0 /
std::sqrt(pi_dbl) *
exp(-(mu_dbl + lambda_dbl * sigma_dbl * sigma_dbl - y_dbl) / (
std::sqrt(2.0) * sigma_dbl) * (mu_dbl + lambda_dbl * sigma_dbl * sigma_dbl - y_dbl) / (sigma_dbl *
std::sqrt(2.0))) /
boost::math::erfc((mu_dbl + lambda_dbl * sigma_dbl * sigma_dbl - y_dbl) / (sigma_dbl *
std::sqrt(2.0)));
101 operands_and_partials.
d_x1[n] += -lambda_dbl + deriv_logerfc * -1.0 / (sigma_dbl *
std::sqrt(2.0));
103 operands_and_partials.
d_x2[n] += lambda_dbl + deriv_logerfc / (sigma_dbl *
std::sqrt(2.0));
105 operands_and_partials.
d_x3[n] += sigma_dbl * lambda_dbl * lambda_dbl + deriv_logerfc * (-mu_dbl / (sigma_dbl * sigma_dbl *
std::sqrt(2.0)) + lambda_dbl /
std::sqrt(2.0) + y_dbl / (sigma_dbl * sigma_dbl *
std::sqrt(2.0)));
107 operands_and_partials.
d_x4[n] += 1 / lambda_dbl + lambda_dbl * sigma_dbl * sigma_dbl + mu_dbl - y_dbl + deriv_logerfc * sigma_dbl /
std::sqrt(2.0);
109 return operands_and_partials.
to_var(logp);
112 template <
bool propto,
113 typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale>
120 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale,
124 exp_mod_normal_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_inv_scale& lambda,
const Policy&) {
125 return exp_mod_normal_log<false>(y,mu,sigma,lambda,Policy());
128 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale>
135 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale,
140 static const char*
function =
"stan::prob::exp_mod_normal_cdf(%1%)";
156 if (!
check_not_nan(
function, y,
"Random variable", &cdf, Policy()))
158 if (!
check_finite(
function, mu,
"Location parameter", &cdf, Policy()))
163 if (!
check_finite(
function, sigma,
"Scale parameter", &cdf, Policy()))
168 if (!
check_finite(
function, lambda,
"Inv_scale parameter", &cdf, Policy()))
175 "Random variable",
"Location parameter",
"Scale parameter",
"Inv_scale paramter",
183 size_t N =
max_size(y, mu, sigma, lambda);
185 for (
size_t n = 0; n < N; n++) {
191 cdf *= 0.5 * (1 +
erf((y_vec[n] - mu_vec[n]) / (
sqrt(2.0) * sigma_vec[n]))) -
exp(-lambda_vec[n] * (y_vec[n] - mu_vec[n]) + lambda_vec[n] * sigma_vec[n] * lambda_vec[n] * sigma_vec[n] / 2.0) * (0.5 * (1 +
erf((y_vec[n] - mu_vec[n] - sigma_vec[n] * lambda_vec[n] * sigma_vec[n]) / (
sqrt(2.0) * sigma_vec[n]))));
197 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_inv_scale>