1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP__
41 template <
bool propto,
typename T_y,
typename T_dof,
42 typename T_loc,
typename T_scale,
44 typename return_type<T_y,T_dof,T_loc,T_scale>::type
48 static const char*
function =
"stan::prob::student_t_log(%1%)";
65 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
67 if(!
check_finite(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
69 if(!
check_positive(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
84 "Random variable",
"Degrees of freedom parameter",
"Location parameter",
"Scale parameter",
96 size_t N =
max_size(y, nu, mu, sigma);
103 for (
size_t n = 0; n < N; n++) {
105 logp +=
lgamma( (nu_vec[n] + 1.0) / 2.0) -
lgamma(nu_vec[n] / 2.0);
107 logp += NEG_LOG_SQRT_PI;
109 logp -= 0.5 *
log(nu_vec[n]);
111 logp -=
log(sigma_vec[n]);
113 logp -= ((nu_vec[n] + 1.0) / 2.0)
114 *
log1p(
square(((y_vec[n] - mu_vec[n]) / sigma_vec[n])) / nu_vec[n]);
119 template <
bool propto,
120 typename T_y,
typename T_dof,
typename T_loc,
typename T_scale>
124 const T_scale& sigma) {
128 template <
typename T_y,
typename T_dof,
typename T_loc,
typename T_scale,
133 const T_scale& sigma,
135 return student_t_log<false>(y,nu,mu,sigma,Policy());
138 template <
typename T_y,
typename T_dof,
typename T_loc,
typename T_scale>
142 const T_scale& sigma) {
146 template <
typename T_y,
typename T_dof,
typename T_loc,
typename T_scale,
class Policy>
147 typename boost::math::tools::promote_args<T_y, T_dof, T_loc, T_scale>::type
148 student_t_cdf(
const T_y& y,
const T_dof& nu,
const T_loc& mu,
const T_scale& sigma,
const Policy&) {
150 static const char*
function =
"stan::prob::student_t_cdf(%1%)";
157 using boost::math::tools::promote_args;
162 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
165 if(!
check_finite(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
168 if(!
check_positive(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
197 using boost::math::ibeta_derivative;
199 using boost::math::digamma;
200 using boost::math::beta;
203 double digammaHalf = 0;
212 digammaHalf = digamma(0.5);
216 const double nu_dbl =
value_of(nu_vec[i]);
218 digammaNu_vec[i] = digamma(0.5 * nu_dbl);
219 digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
220 betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);
227 for (
size_t n = 0; n < N; n++) {
229 const double sigma_inv = 1.0 /
value_of(sigma_vec[n]);
231 const double nu_dbl =
value_of(nu_vec[n]);
232 const double q = nu_dbl / (t * t);
233 const double r = 1.0 / (1.0 + q);
234 double J = - 2 * r * r * q / t;
239 double z =
ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);
241 const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
243 double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);
248 operands_and_partials.
d_x1[n]
249 += (d_ibeta * J * sigma_inv) / Pn;
257 digammaNu_vec[n], digammaHalf, digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);
259 operands_and_partials.
d_x2[n]
260 += 0.5 * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;
265 operands_and_partials.
d_x3[n]
266 += (- d_ibeta * J * sigma_inv) / Pn;
269 operands_and_partials.
d_x4[n]
270 += (- d_ibeta * J * sigma_inv * t) / Pn;
276 double z = 1.0 -
ibeta(0.5, 0.5 * nu_dbl, r);
278 const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
280 double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);
285 operands_and_partials.
d_x1[n]
286 += (d_ibeta * J * sigma_inv) / Pn;
294 digammaHalf, digammaNu_vec[n], digammaNuPlusHalf_vec[n], betaNuHalf_vec[n]);
296 operands_and_partials.
d_x2[n]
297 += 0.5 * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;
302 operands_and_partials.
d_x3[n]
303 += (- d_ibeta * J * sigma_inv) / Pn;
306 operands_and_partials.
d_x4[n]
307 += (- d_ibeta * J * sigma_inv * t) / Pn;
311 if(t > 0) operands_and_partials.
d_x2[n] *= -1;
315 for (
size_t n = 0; n < N; n++) {
318 operands_and_partials.
d_x1[n] *= P;
321 operands_and_partials.
d_x2[n] *= P;
324 operands_and_partials.
d_x3[n] *= P;
327 operands_and_partials.
d_x4[n] *= P;
331 return operands_and_partials.
to_var(P);
335 template <
typename T_y,
typename T_dof,
typename T_loc,
typename T_scale>
336 typename boost::math::tools::promote_args<T_y,T_dof,T_loc,T_scale>::type
337 student_t_cdf(
const T_y& y,
const T_dof& nu,
const T_loc& mu,
const T_scale& sigma) {