Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
student_t.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP
2 #define STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__STUDENT_T_HPP
3 
4 #include <boost/random/student_t_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
12 #include <stan/meta/traits.hpp>
13 #include <stan/prob/constants.hpp>
14 #include <stan/prob/traits.hpp>
16 
17 namespace stan {
18 
19  namespace prob {
20 
46  template <bool propto, typename T_y, typename T_dof,
47  typename T_loc, typename T_scale>
48  typename return_type<T_y,T_dof,T_loc,T_scale>::type
49  student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
50  const T_scale& sigma) {
51  static const char* function = "stan::prob::student_t_log(%1%)";
52 
57 
58  // check if any vectors are zero length
59  if (!(stan::length(y)
60  && stan::length(nu)
61  && stan::length(mu)
62  && stan::length(sigma)))
63  return 0.0;
64 
65  double logp(0.0);
66 
67  // validate args (here done over var, which should be OK)
68  check_not_nan(function, y, "Random variable", &logp);
69  check_positive_finite(function, nu, "Degrees of freedom parameter",
70  &logp);
71  check_finite(function, mu, "Location parameter", &logp);
72  check_positive_finite(function, sigma, "Scale parameter", &logp);
73  check_consistent_sizes(function,
74  y,nu,mu,sigma,
75  "Random variable",
76  "Degrees of freedom parameter",
77  "Location parameter","Scale parameter",
78  &logp);
79 
80  // check if no variables are involved and prop-to
82  return 0.0;
83 
84  VectorView<const T_y> y_vec(y);
85  VectorView<const T_dof> nu_vec(nu);
86  VectorView<const T_loc> mu_vec(mu);
87  VectorView<const T_scale> sigma_vec(sigma);
88  size_t N = max_size(y, nu, mu, sigma);
89 
90  using std::log;
92  using boost::math::lgamma;
93  using stan::math::square;
95 
97  is_vector<T_dof>::value> half_nu(length(nu));
98  for (size_t i = 0; i < length(nu); i++)
100  half_nu[i] = 0.5 * value_of(nu_vec[i]);
102  is_vector<T_dof>::value> lgamma_half_nu(length(nu));
104  is_vector<T_dof>::value> lgamma_half_nu_plus_half(length(nu));
106  for (size_t i = 0; i < length(nu); i++) {
107  lgamma_half_nu[i] = lgamma(half_nu[i]);
108  lgamma_half_nu_plus_half[i] = lgamma(half_nu[i] + 0.5);
109  }
111  is_vector<T_dof>::value> digamma_half_nu(length(nu));
113  is_vector<T_dof>::value> digamma_half_nu_plus_half(length(nu));
115  for (size_t i = 0; i < length(nu); i++) {
116  digamma_half_nu[i] = digamma(half_nu[i]);
117  digamma_half_nu_plus_half[i] = digamma(half_nu[i] + 0.5);
118  }
119 
120 
121 
123  is_vector<T_dof>::value> log_nu(length(nu));
124  for (size_t i = 0; i < length(nu); i++)
126  log_nu[i] = log(value_of(nu_vec[i]));
128  is_vector<T_scale>::value> log_sigma(length(sigma));
129  for (size_t i = 0; i < length(sigma); i++)
131  log_sigma[i] = log(value_of(sigma_vec[i]));
132 
138  square_y_minus_mu_over_sigma__over_nu(N);
139 
145  log1p_exp(N);
146 
147  for (size_t i = 0; i < N; i++)
149  const double y_dbl = value_of(y_vec[i]);
150  const double mu_dbl = value_of(mu_vec[i]);
151  const double sigma_dbl = value_of(sigma_vec[i]);
152  const double nu_dbl = value_of(nu_vec[i]);
153  square_y_minus_mu_over_sigma__over_nu[i]
154  = square((y_dbl - mu_dbl) / sigma_dbl) / nu_dbl;
155  log1p_exp[i] = log1p(square_y_minus_mu_over_sigma__over_nu[i]);
156  }
157 
159  operands_and_partials(y,nu,mu,sigma);
160  for (size_t n = 0; n < N; n++) {
161  const double y_dbl = value_of(y_vec[n]);
162  const double mu_dbl = value_of(mu_vec[n]);
163  const double sigma_dbl = value_of(sigma_vec[n]);
164  const double nu_dbl = value_of(nu_vec[n]);
166  logp += NEG_LOG_SQRT_PI;
168  logp += lgamma_half_nu_plus_half[n] - lgamma_half_nu[n]
169  - 0.5 * log_nu[n];
171  logp -= log_sigma[n];
173  logp -= (half_nu[n] + 0.5)
174  * log1p_exp[n];
175 
177  operands_and_partials.d_x1[n]
178  += -(half_nu[n]+0.5)
179  * 1.0 / (1.0 + square_y_minus_mu_over_sigma__over_nu[n])
180  * (2.0 * (y_dbl - mu_dbl) / square(sigma_dbl) / nu_dbl);
181  }
183  const double inv_nu = 1.0 / nu_dbl;
184  operands_and_partials.d_x2[n]
185  += 0.5*digamma_half_nu_plus_half[n] - 0.5*digamma_half_nu[n]
186  - 0.5 * inv_nu
187  - 0.5*log1p_exp[n]
188  + (half_nu[n] + 0.5)
189  * (1.0/(1.0 + square_y_minus_mu_over_sigma__over_nu[n])
190  * square_y_minus_mu_over_sigma__over_nu[n] * inv_nu);
191  }
193  operands_and_partials.d_x3[n]
194  -= (half_nu[n] + 0.5)
195  / (1.0 + square_y_minus_mu_over_sigma__over_nu[n])
196  * (2.0 * (mu_dbl - y_dbl) / (sigma_dbl*sigma_dbl*nu_dbl));
197  }
199  const double inv_sigma = 1.0 / sigma_dbl;
200  operands_and_partials.d_x4[n]
201  += -inv_sigma
202  + (nu_dbl + 1.0) / (1.0 + square_y_minus_mu_over_sigma__over_nu[n])
203  * (square_y_minus_mu_over_sigma__over_nu[n] * inv_sigma);
204  }
205  }
206  return operands_and_partials.to_var(logp);
207  }
208 
209  template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
210  inline
212  student_t_log(const T_y& y, const T_dof& nu, const T_loc& mu,
213  const T_scale& sigma) {
214  return student_t_log<false>(y,nu,mu,sigma);
215  }
216 
217  template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
219  student_t_cdf(const T_y& y, const T_dof& nu, const T_loc& mu,
220  const T_scale& sigma) {
221 
222  // Size checks
223  if (!(stan::length(y) && stan::length(nu) && stan::length(mu)
224  && stan::length(sigma)))
225  return 1.0;
226 
227  static const char* function = "stan::prob::student_t_cdf(%1%)";
228 
233  using stan::math::value_of;
234 
235  double P(1.0);
236 
237  check_not_nan(function, y, "Random variable", &P);
238  check_positive_finite(function, nu, "Degrees of freedom parameter", &P);
239  check_finite(function, mu, "Location parameter", &P);
240  check_positive_finite(function, sigma, "Scale parameter", &P);
241 
242  // Wrap arguments in vectors
243  VectorView<const T_y> y_vec(y);
244  VectorView<const T_dof> nu_vec(nu);
245  VectorView<const T_loc> mu_vec(mu);
246  VectorView<const T_scale> sigma_vec(sigma);
247  size_t N = max_size(y, nu, mu, sigma);
248 
250  operands_and_partials(y, nu, mu, sigma);
251 
252  // Explicit return for extreme values
253  // The gradients are technically ill-defined, but treated as zero
254  for (size_t i = 0; i < stan::length(y); i++) {
255  if (value_of(y_vec[i]) == -std::numeric_limits<double>::infinity())
256  return operands_and_partials.to_var(0.0);
257  }
258 
259  using boost::math::ibeta;
260  using boost::math::ibeta_derivative;
261  using boost::math::digamma;
262  using boost::math::beta;
263 
264  // Cache a few expensive function calls if nu is a parameter
265  double digammaHalf = 0;
266 
268  digamma_vec(stan::length(nu));
270  digammaNu_vec(stan::length(nu));
272  digammaNuPlusHalf_vec(stan::length(nu));
274  betaNuHalf_vec(stan::length(nu));
275 
277  digammaHalf = digamma(0.5);
278 
279  for (size_t i = 0; i < stan::length(nu); i++) {
280  const double nu_dbl = value_of(nu_vec[i]);
281 
282  digammaNu_vec[i] = digamma(0.5 * nu_dbl);
283  digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
284  betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);
285  }
286  }
287 
288  // Compute vectorized CDF and gradient
289  for (size_t n = 0; n < N; n++) {
290 
291  // Explicit results for extreme values
292  // The gradients are technically ill-defined, but treated as zero
293  if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
294  continue;
295  }
296 
297  const double sigma_inv = 1.0 / value_of(sigma_vec[n]);
298  const double t = (value_of(y_vec[n]) - value_of(mu_vec[n])) * sigma_inv;
299  const double nu_dbl = value_of(nu_vec[n]);
300  const double q = nu_dbl / (t * t);
301  const double r = 1.0 / (1.0 + q);
302  const double J = 2 * r * r * q / t;
303  double zJacobian = t > 0 ? - 0.5 : 0.5;
304 
305  if(q < 2)
306  {
307 
308  double z = ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);
309  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
310  const double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);
311 
312  P *= Pn;
313 
315  operands_and_partials.d_x1[n]
316  += - zJacobian * d_ibeta * J * sigma_inv / Pn;
318 
319  double g1 = 0;
320  double g2 = 0;
321 
322  stan::math::gradRegIncBeta(g1, g2, 0.5 * nu_dbl, 0.5, 1.0 - r,
323  digammaNu_vec[n], digammaHalf,
324  digammaNuPlusHalf_vec[n],
325  betaNuHalf_vec[n]);
326 
327  operands_and_partials.d_x2[n]
328  += zJacobian * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;
329  }
330 
332  operands_and_partials.d_x3[n]
333  += zJacobian * d_ibeta * J * sigma_inv / Pn;
335  operands_and_partials.d_x4[n]
336  += zJacobian * d_ibeta * J * sigma_inv * t / Pn;
337 
338  }
339  else {
340 
341  double z = 1 - ibeta(0.5, 0.5 * nu_dbl, r);
342  zJacobian *= -1;
343 
344  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
345 
346  double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);
347 
348  P *= Pn;
349 
351  operands_and_partials.d_x1[n]
352  += zJacobian * d_ibeta * J * sigma_inv / Pn;
354 
355  double g1 = 0;
356  double g2 = 0;
357 
358  stan::math::gradRegIncBeta(g1, g2, 0.5, 0.5 * nu_dbl, r,
359  digammaHalf, digammaNu_vec[n],
360  digammaNuPlusHalf_vec[n],
361  betaNuHalf_vec[n]);
362 
363  operands_and_partials.d_x2[n]
364  += zJacobian * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;
365  }
367  operands_and_partials.d_x3[n]
368  += - zJacobian * d_ibeta * J * sigma_inv / Pn;
370  operands_and_partials.d_x4[n]
371  += - zJacobian * d_ibeta * J * sigma_inv * t / Pn;
372  }
373  }
374 
376  for(size_t n = 0; n < stan::length(y); ++n)
377  operands_and_partials.d_x1[n] *= P;
379  for(size_t n = 0; n < stan::length(nu); ++n)
380  operands_and_partials.d_x2[n] *= P;
382  for(size_t n = 0; n < stan::length(mu); ++n)
383  operands_and_partials.d_x3[n] *= P;
385  for(size_t n = 0; n < stan::length(sigma); ++n)
386  operands_and_partials.d_x4[n] *= P;
387 
388  return operands_and_partials.to_var(P);
389  }
390 
391  template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
393  student_t_cdf_log(const T_y& y, const T_dof& nu, const T_loc& mu,
394  const T_scale& sigma) {
395 
396  // Size checks
397  if (!(stan::length(y) && stan::length(nu) && stan::length(mu)
398  && stan::length(sigma)))
399  return 0.0;
400 
401  static const char* function = "stan::prob::student_t_cdf_log(%1%)";
402 
407  using stan::math::value_of;
408 
409  double P(0.0);
410 
411  check_not_nan(function, y, "Random variable", &P);
412  check_positive_finite(function, nu, "Degrees of freedom parameter", &P);
413  check_finite(function, mu, "Location parameter", &P);
414  check_positive_finite(function, sigma, "Scale parameter", &P);
415 
416  // Wrap arguments in vectors
417  VectorView<const T_y> y_vec(y);
418  VectorView<const T_dof> nu_vec(nu);
419  VectorView<const T_loc> mu_vec(mu);
420  VectorView<const T_scale> sigma_vec(sigma);
421  size_t N = max_size(y, nu, mu, sigma);
422 
424  operands_and_partials(y, nu, mu, sigma);
425 
426  // Explicit return for extreme values
427  // The gradients are technically ill-defined, but treated as zero
428  for (size_t i = 0; i < stan::length(y); i++) {
429  if (value_of(y_vec[i]) == -std::numeric_limits<double>::infinity())
430  return operands_and_partials.to_var(stan::math::negative_infinity());
431  }
432 
433  using boost::math::ibeta;
434  using boost::math::ibeta_derivative;
435  using boost::math::digamma;
436  using boost::math::beta;
437 
438  // Cache a few expensive function calls if nu is a parameter
439  double digammaHalf = 0;
440 
442  digamma_vec(stan::length(nu));
444  digammaNu_vec(stan::length(nu));
446  digammaNuPlusHalf_vec(stan::length(nu));
448  betaNuHalf_vec(stan::length(nu));
449 
451  digammaHalf = digamma(0.5);
452 
453  for (size_t i = 0; i < stan::length(nu); i++) {
454  const double nu_dbl = value_of(nu_vec[i]);
455 
456  digammaNu_vec[i] = digamma(0.5 * nu_dbl);
457  digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
458  betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);
459  }
460  }
461 
462  // Compute vectorized cdf_log and gradient
463  for (size_t n = 0; n < N; n++) {
464 
465  // Explicit results for extreme values
466  // The gradients are technically ill-defined, but treated as zero
467  if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
468  continue;
469  }
470 
471  const double sigma_inv = 1.0 / value_of(sigma_vec[n]);
472  const double t = (value_of(y_vec[n]) - value_of(mu_vec[n])) * sigma_inv;
473  const double nu_dbl = value_of(nu_vec[n]);
474  const double q = nu_dbl / (t * t);
475  const double r = 1.0 / (1.0 + q);
476  const double J = 2 * r * r * q / t;
477  double zJacobian = t > 0 ? - 0.5 : 0.5;
478 
479  if(q < 2) {
480  double z = ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);
481  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
482  const double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);
483 
484  P += log(Pn);
485 
487  operands_and_partials.d_x1[n]
488  += - zJacobian * d_ibeta * J * sigma_inv / Pn;
489 
491 
492  double g1 = 0;
493  double g2 = 0;
494 
495  stan::math::gradRegIncBeta(g1, g2, 0.5 * nu_dbl, 0.5, 1.0 - r,
496  digammaNu_vec[n], digammaHalf,
497  digammaNuPlusHalf_vec[n],
498  betaNuHalf_vec[n]);
499 
500  operands_and_partials.d_x2[n]
501  += zJacobian * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;
502  }
503 
505  operands_and_partials.d_x3[n]
506  += zJacobian * d_ibeta * J * sigma_inv / Pn;
508  operands_and_partials.d_x4[n]
509  += zJacobian * d_ibeta * J * sigma_inv * t / Pn;
510 
511  }
512  else {
513 
514  double z = 1 - ibeta(0.5, 0.5 * nu_dbl, r);
515  zJacobian *= -1;
516 
517  const double Pn = t > 0 ? 1.0 - 0.5 * z : 0.5 * z;
518 
519  double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);
520 
521  P += log(Pn);
522 
524  operands_and_partials.d_x1[n]
525  += zJacobian * d_ibeta * J * sigma_inv / Pn;
526 
528 
529  double g1 = 0;
530  double g2 = 0;
531 
532  stan::math::gradRegIncBeta(g1, g2, 0.5, 0.5 * nu_dbl, r,
533  digammaHalf, digammaNu_vec[n],
534  digammaNuPlusHalf_vec[n],
535  betaNuHalf_vec[n]);
536 
537  operands_and_partials.d_x2[n]
538  += zJacobian * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;
539  }
540 
542  operands_and_partials.d_x3[n]
543  += - zJacobian * d_ibeta * J * sigma_inv / Pn;
545  operands_and_partials.d_x4[n]
546  += - zJacobian * d_ibeta * J * sigma_inv * t / Pn;
547  }
548  }
549 
550  return operands_and_partials.to_var(P);
551  }
552 
553  template <typename T_y, typename T_dof, typename T_loc, typename T_scale>
555  student_t_ccdf_log(const T_y& y, const T_dof& nu, const T_loc& mu,
556  const T_scale& sigma) {
557 
558  // Size checks
559  if (!(stan::length(y) && stan::length(nu) && stan::length(mu)
560  && stan::length(sigma)))
561  return 0.0;
562 
563  static const char* function = "stan::prob::student_t_ccdf_log(%1%)";
564 
569  using stan::math::value_of;
570 
571  double P(0.0);
572 
573  check_not_nan(function, y, "Random variable", &P);
574  check_positive_finite(function, nu, "Degrees of freedom parameter", &P);
575  check_finite(function, mu, "Location parameter", &P);
576  check_positive_finite(function, sigma, "Scale parameter", &P);
577 
578  // Wrap arguments in vectors
579  VectorView<const T_y> y_vec(y);
580  VectorView<const T_dof> nu_vec(nu);
581  VectorView<const T_loc> mu_vec(mu);
582  VectorView<const T_scale> sigma_vec(sigma);
583  size_t N = max_size(y, nu, mu, sigma);
584 
586  operands_and_partials(y, nu, mu, sigma);
587 
588  // Explicit return for extreme values
589  // The gradients are technically ill-defined, but treated as zero
590  for (size_t i = 0; i < stan::length(y); i++) {
591  if (value_of(y_vec[i]) == -std::numeric_limits<double>::infinity())
592  return operands_and_partials.to_var(0.0);
593  }
594 
595  using boost::math::ibeta;
596  using boost::math::ibeta_derivative;
597  using boost::math::digamma;
598  using boost::math::beta;
599 
600  // Cache a few expensive function calls if nu is a parameter
601  double digammaHalf = 0;
602 
604  digamma_vec(stan::length(nu));
606  digammaNu_vec(stan::length(nu));
608  digammaNuPlusHalf_vec(stan::length(nu));
610  betaNuHalf_vec(stan::length(nu));
611 
613  digammaHalf = digamma(0.5);
614 
615  for (size_t i = 0; i < stan::length(nu); i++) {
616  const double nu_dbl = value_of(nu_vec[i]);
617 
618  digammaNu_vec[i] = digamma(0.5 * nu_dbl);
619  digammaNuPlusHalf_vec[i] = digamma(0.5 + 0.5 * nu_dbl);
620  betaNuHalf_vec[i] = beta(0.5, 0.5 * nu_dbl);
621  }
622  }
623 
624  // Compute vectorized cdf_log and gradient
625  for (size_t n = 0; n < N; n++) {
626 
627  // Explicit results for extreme values
628  // The gradients are technically ill-defined, but treated as zero
629  if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
630  return operands_and_partials.to_var(stan::math::negative_infinity());
631  }
632 
633  const double sigma_inv = 1.0 / value_of(sigma_vec[n]);
634  const double t = (value_of(y_vec[n]) - value_of(mu_vec[n])) * sigma_inv;
635  const double nu_dbl = value_of(nu_vec[n]);
636  const double q = nu_dbl / (t * t);
637  const double r = 1.0 / (1.0 + q);
638  const double J = 2 * r * r * q / t;
639  double zJacobian = t > 0 ? - 0.5 : 0.5;
640 
641  if(q < 2) {
642  double z = ibeta(0.5 * nu_dbl, 0.5, 1.0 - r);
643  const double Pn = t > 0 ? 0.5 * z : 1.0 - 0.5 * z;
644  const double d_ibeta = ibeta_derivative(0.5 * nu_dbl, 0.5, 1.0 - r);
645 
646  P += log(Pn);
647 
649  operands_and_partials.d_x1[n]
650  += zJacobian * d_ibeta * J * sigma_inv / Pn;
651 
653 
654  double g1 = 0;
655  double g2 = 0;
656 
657  stan::math::gradRegIncBeta(g1, g2, 0.5 * nu_dbl, 0.5, 1.0 - r,
658  digammaNu_vec[n], digammaHalf,
659  digammaNuPlusHalf_vec[n],
660  betaNuHalf_vec[n]);
661 
662  operands_and_partials.d_x2[n]
663  -= zJacobian * ( d_ibeta * (r / t) * (r / t) + 0.5 * g1 ) / Pn;
664  }
665 
667  operands_and_partials.d_x3[n]
668  -= zJacobian * d_ibeta * J * sigma_inv / Pn;
670  operands_and_partials.d_x4[n]
671  -= zJacobian * d_ibeta * J * sigma_inv * t / Pn;
672 
673  }
674  else {
675 
676  double z = 1 - ibeta(0.5, 0.5 * nu_dbl, r);
677  zJacobian *= -1;
678 
679  const double Pn = t > 0 ? 0.5 * z : 1.0 - 0.5 * z;
680 
681  double d_ibeta = ibeta_derivative(0.5, 0.5 * nu_dbl, r);
682 
683  P += log(Pn);
684 
686  operands_and_partials.d_x1[n]
687  -= zJacobian * d_ibeta * J * sigma_inv / Pn;
688 
690 
691  double g1 = 0;
692  double g2 = 0;
693 
694  stan::math::gradRegIncBeta(g1, g2, 0.5, 0.5 * nu_dbl, r,
695  digammaHalf, digammaNu_vec[n],
696  digammaNuPlusHalf_vec[n],
697  betaNuHalf_vec[n]);
698 
699  operands_and_partials.d_x2[n]
700  -= zJacobian * ( - d_ibeta * (r / t) * (r / t) + 0.5 * g2 ) / Pn;
701  }
702 
704  operands_and_partials.d_x3[n]
705  += zJacobian * d_ibeta * J * sigma_inv / Pn;
707  operands_and_partials.d_x4[n]
708  += zJacobian * d_ibeta * J * sigma_inv * t / Pn;
709  }
710  }
711 
712  return operands_and_partials.to_var(P);
713  }
714 
715  template <class RNG>
716  inline double
717  student_t_rng(const double nu,
718  const double mu,
719  const double sigma,
720  RNG& rng) {
721  using boost::variate_generator;
722  using boost::random::student_t_distribution;
723 
724  static const char* function = "stan::prob::student_t_rng(%1%)";
725 
728 
729  check_positive_finite(function, nu, "Degrees of freedom parameter",
730  (double*)0);
731  check_finite(function, mu, "Location parameter", (double*)0);
732  check_positive_finite(function, sigma, "Scale parameter", (double*)0);
733 
734  variate_generator<RNG&, student_t_distribution<> >
735  rng_unit_student_t(rng, student_t_distribution<>(nu));
736  return mu + sigma * rng_unit_student_t();
737  }
738  }
739 }
740 #endif
T square(const T x)
Return the square of the specified argument.
Definition: square.hpp:22
fvar< T > log1p_exp(const fvar< T > &x)
Definition: log1p_exp.hpp:15
void gradRegIncBeta(double &g1, double &g2, double a, double b, double z, double digammaA, double digammaB, double digammaSum, double betaAB)
return_type< T_y, T_dof, T_loc, T_scale >::type student_t_cdf(const T_y &y, const T_dof &nu, const T_loc &mu, const T_scale &sigma)
Definition: student_t.hpp:219
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
size_t length(const T &)
Definition: traits.hpp:159
fvar< T > square(const fvar< T > &x)
Definition: square.hpp:15
DoubleVectorView allocates double values to be used as intermediate values.
Definition: traits.hpp:358
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is finite.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
Definition: value_of.hpp:16
fvar< T > lgamma(const fvar< T > &x)
Definition: lgamma.hpp:15
A variable implementation that stores operands and derivatives with respect to the variable...
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Definition: traits.hpp:406
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
Definition: traits.hpp:57
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Definition: value_of.hpp:24
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Definition: traits.hpp:35
VectorView< double *, is_vector< T2 >::value, is_constant_struct< T2 >::value > d_x2
var ibeta(const var &a, const var &b, const var &x)
The normalized incomplete beta function of a, b, and x.
Definition: ibeta.hpp:223
return_type< T_y, T_dof, T_loc, T_scale >::type student_t_log(const T_y &y, const T_dof &nu, const T_loc &mu, const T_scale &sigma)
The log of the Student-t density for the given y, nu, mean, and scale parameter.
Definition: student_t.hpp:49
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result)
size_t max_size(const T1 &x1, const T2 &x2)
Definition: traits.hpp:191
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
return_type< T_y, T_dof, T_loc, T_scale >::type student_t_cdf_log(const T_y &y, const T_dof &nu, const T_loc &mu, const T_scale &sigma)
Definition: student_t.hpp:393
VectorView< double *, is_vector< T4 >::value, is_constant_struct< T4 >::value > d_x4
fvar< T > digamma(const fvar< T > &x)
Definition: digamma.hpp:16
VectorView< double *, is_vector< T1 >::value, is_constant_struct< T1 >::value > d_x1
VectorView< double *, is_vector< T3 >::value, is_constant_struct< T3 >::value > d_x3
return_type< T_y, T_dof, T_loc, T_scale >::type student_t_ccdf_log(const T_y &y, const T_dof &nu, const T_loc &mu, const T_scale &sigma)
Definition: student_t.hpp:555
double student_t_rng(const double nu, const double mu, const double sigma, RNG &rng)
Definition: student_t.hpp:717
fvar< T > log(const fvar< T > &x)
Definition: log.hpp:15
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
Definition: traits.hpp:275
fvar< T > log1p(const fvar< T > &x)
Definition: log1p.hpp:16
double negative_infinity()
Return negative infinity.
Definition: constants.hpp:123

     [ Stan Home Page ] © 2011–2014, Stan Development Team.