1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__SKEW__NORMAL__HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__SKEW__NORMAL__HPP__
4 #include <boost/random/variate_generator.hpp>
5 #include <boost/math/distributions.hpp>
21 template <
bool propto,
22 typename T_y,
typename T_loc,
typename T_scale,
typename T_shape,
24 typename return_type<T_y,T_loc,T_scale,T_shape>::type
26 const T_shape& alpha,
const Policy& ) {
27 static const char*
function =
"stan::prob::skew_normal_log(%1%)";
49 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
62 "Random variable",
"Location parameter",
"Scale parameter",
"Shape paramter",
77 size_t N =
max_size(y, mu, sigma, alpha);
81 for (
size_t i = 0; i <
length(sigma); i++) {
82 inv_sigma[i] = 1.0 /
value_of(sigma_vec[i]);
87 for (
size_t n = 0; n < N; n++) {
89 const double y_dbl =
value_of(y_vec[n]);
90 const double mu_dbl =
value_of(mu_vec[n]);
91 const double sigma_dbl =
value_of(sigma_vec[n]);
92 const double alpha_dbl =
value_of(alpha_vec[n]);
95 const double y_minus_mu_over_sigma
96 = (y_dbl - mu_dbl) * inv_sigma[n];
97 const double pi_dbl = boost::math::constants::pi<double>();
101 logp -= 0.5 *
log(2.0 * pi_dbl);
103 logp -=
log(sigma_dbl);
105 logp -= y_minus_mu_over_sigma * y_minus_mu_over_sigma / 2.0;
112 operands_and_partials.
d_x1[n] += -y_minus_mu_over_sigma / sigma_dbl + deriv_logerf * alpha_dbl / (sigma_dbl *
std::sqrt(2.0)) ;
114 operands_and_partials.
d_x2[n] += y_minus_mu_over_sigma / sigma_dbl + deriv_logerf * -alpha_dbl / (sigma_dbl *
std::sqrt(2.0));
116 operands_and_partials.
d_x3[n] += -1.0 / sigma_dbl + y_minus_mu_over_sigma * y_minus_mu_over_sigma / sigma_dbl - deriv_logerf * y_minus_mu_over_sigma * alpha_dbl / (sigma_dbl *
std::sqrt(2.0));
118 operands_and_partials.
d_x4[n] += deriv_logerf * y_minus_mu_over_sigma /
std::sqrt(2.0);
120 return operands_and_partials.
to_var(logp);
124 template <
bool propto,
125 typename T_y,
typename T_loc,
typename T_scale,
typename T_shape>
128 skew_normal_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_shape& alpha) {
132 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_shape,
136 skew_normal_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_shape& alpha,
const Policy&) {
137 return skew_normal_log<false>(y,mu,sigma,alpha,Policy());
140 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_shape>
143 skew_normal_log(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_shape& alpha) {
147 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_shape,
150 skew_normal_cdf(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_shape& alpha,
152 static const char*
function =
"stan::prob::skew_normal_cdf(%1%)";
170 if (!
check_not_nan(
function, y,
"Random variable", &cdf, Policy()))
172 if (!
check_finite(
function, mu,
"Location parameter", &cdf, Policy()))
180 if (!
check_finite(
function, alpha,
"Shape parameter", &cdf, Policy()))
187 "Random variable",
"Location parameter",
"Scale parameter",
"Shape paramter",
195 size_t N =
max_size(y, mu, sigma, alpha);
197 for (
size_t n = 0; n < N; n++) {
198 cdf *= 0.5 *
erfc(-(y_vec[n] - mu_vec[n]) / (
std::sqrt(2) * sigma_vec[n])) - 2 *
owens_t((y_vec[n] - mu_vec[n]) / sigma_vec[n], alpha_vec[n]);
203 template <
typename T_y,
typename T_loc,
typename T_scale,
typename T_shape>
206 skew_normal_cdf(
const T_y& y,
const T_loc& mu,
const T_scale& sigma,
const T_shape& alpha) {
216 boost::math::skew_normal_distribution<>
dist (mu, sigma, alpha);