Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
gamma.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__GAMMA_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__GAMMA_HPP__
3 
4 #include <boost/random/gamma_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
7 #include <stan/agrad.hpp>
10 #include <stan/meta/traits.hpp>
11 #include <stan/prob/constants.hpp>
12 #include <stan/prob/traits.hpp>
13 
14 namespace stan {
15 
16  namespace prob {
17 
40  template <bool propto,
41  typename T_y, typename T_shape, typename T_inv_scale,
42  class Policy>
43  typename return_type<T_y,T_shape,T_inv_scale>::type
44  gamma_log(const T_y& y, const T_shape& alpha, const T_inv_scale& beta,
45  const Policy&) {
46  static const char* function = "stan::prob::gamma_log(%1%)";
47 
55 
56  // check if any vectors are zero length
57  if (!(stan::length(y)
58  && stan::length(alpha)
59  && stan::length(beta)))
60  return 0.0;
61 
62  // set up return value accumulator
63  double logp(0.0);
64 
65  // validate args (here done over var, which should be OK)
66  if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
67  return logp;
68  if (!check_finite(function, alpha, "Shape parameter",
69  &logp, Policy()))
70  return logp;
71  if (!check_positive(function, alpha, "Shape parameter",
72  &logp, Policy()))
73  return logp;
74  if (!check_finite(function, beta, "Inverse scale parameter",
75  &logp, Policy()))
76  return logp;
77  if (!check_positive(function, beta, "Inverse scale parameter",
78  &logp, Policy()))
79  return logp;
80  if (!(check_consistent_sizes(function,
81  y,alpha,beta,
82  "Random variable","Shape parameter","Inverse scale parameter",
83  &logp, Policy())))
84  return logp;
85 
86  // check if no variables are involved and prop-to
88  return 0.0;
89 
90  // set up template expressions wrapping scalars into vector views
91  VectorView<const T_y> y_vec(y);
92  VectorView<const T_shape> alpha_vec(alpha);
93  VectorView<const T_inv_scale> beta_vec(beta);
94 
95  for (size_t n = 0; n < length(y); n++) {
96  const double y_dbl = value_of(y_vec[n]);
97  if (y_dbl < 0)
98  return LOG_ZERO;
99  }
100 
101  size_t N = max_size(y, alpha, beta);
102  agrad::OperandsAndPartials<T_y, T_shape, T_inv_scale> operands_and_partials(y, alpha, beta);
103 
104  using boost::math::lgamma;
106  using boost::math::digamma;
107 
109  log_y(length(y));
111  for(size_t n = 0; n < length(y); n++) {
112  if (value_of(y_vec[n]) > 0)
113  log_y[n] = log(value_of(y_vec[n]));
114  }
115 
117  lgamma_alpha(length(alpha));
119  digamma_alpha(length(alpha));
120  for (size_t n = 0; n < length(alpha); n++) {
122  lgamma_alpha[n] = lgamma(value_of(alpha_vec[n]));
124  digamma_alpha[n] = digamma(value_of(alpha_vec[n]));
125  }
126 
128  log_beta(length(beta));
130  for (size_t n = 0; n < length(beta); n++)
131  log_beta[n] = log(value_of(beta_vec[n]));
132 
133  for (size_t n = 0; n < N; n++) {
134  // pull out values of arguments
135  const double y_dbl = value_of(y_vec[n]);
136  const double alpha_dbl = value_of(alpha_vec[n]);
137  const double beta_dbl = value_of(beta_vec[n]);
138 
140  logp -= lgamma_alpha[n];
142  logp += alpha_dbl * log_beta[n];
144  logp += (alpha_dbl-1.0) * log_y[n];
146  logp -= beta_dbl * y_dbl;
147 
148  // gradients
150  operands_and_partials.d_x1[n] += (alpha_dbl-1)/y_dbl - beta_dbl;
152  operands_and_partials.d_x2[n] += -digamma_alpha[n] + log_beta[n] + log_y[n];
154  operands_and_partials.d_x3[n] += alpha_dbl / beta_dbl - y_dbl;
155  }
156  return operands_and_partials.to_var(logp);
157  }
158 
159  template <bool propto,
160  typename T_y, typename T_shape, typename T_inv_scale>
161  inline
163  gamma_log(const T_y& y, const T_shape& alpha, const T_inv_scale& beta) {
164  return gamma_log<propto>(y,alpha,beta,stan::math::default_policy());
165  }
166 
167  template <typename T_y, typename T_shape, typename T_inv_scale,
168  class Policy>
169  inline
171  gamma_log(const T_y& y, const T_shape& alpha, const T_inv_scale& beta,
172  const Policy&) {
173  return gamma_log<false>(y,alpha,beta,Policy());
174  }
175 
176  template <typename T_y, typename T_shape, typename T_inv_scale>
177  inline
179  gamma_log(const T_y& y, const T_shape& alpha, const T_inv_scale& beta) {
180  return gamma_log<false>(y,alpha,beta,stan::math::default_policy());
181  }
182 
183 
198  /*template <typename T_y, typename T_shape, typename T_inv_scale,
199  class Policy>
200  typename boost::math::tools::promote_args<T_y,T_shape,T_inv_scale>::type
201  gamma_cdf(const T_y& y, const T_shape& alpha, const T_inv_scale& beta,
202  const Policy&) {
203  static const char* function = "stan::prob::gamma_cdf(%1%)";
204 
205  using stan::math::check_finite;
206  using stan::math::check_positive;
207  using stan::math::check_nonnegative;
208  using boost::math::tools::promote_args;
209 
210  typename promote_args<T_y,T_shape,T_inv_scale>::type result;
211  if (!check_finite(function, y, "Random variable", &result, Policy()))
212  return result;
213  if (!check_nonnegative(function, y, "Random variable", &result,
214  Policy()))
215  return result;
216  if (!check_finite(function, alpha, "Shape parameter", &result,
217  Policy()))
218  return result;
219  if (!check_positive(function, alpha, "Shape parameter", &result,
220  Policy()))
221  return result;
222  if (!check_finite(function, beta, "Inverse scale parameter",
223  &result, Policy()))
224  return result;
225  if (!check_positive(function, beta, "Inverse scale parameter",
226  &result, Policy()))
227  return result;
228 
229  // FIXME: implement gamma cdf
230  return boost::math::gamma_p(alpha, y*beta);
231  }
232 
233  template <typename T_y, typename T_shape, typename T_inv_scale>
234  inline
235  typename boost::math::tools::promote_args<T_y,T_shape,T_inv_scale>::type
236  gamma_cdf(const T_y& y, const T_shape& alpha, const T_inv_scale& beta) {
237  return gamma_cdf(y,alpha,beta,stan::math::default_policy());
238  }
239  */
240 
241  template <class RNG>
242  inline double
243  gamma_rng(const double alpha,
244  const double beta,
245  RNG& rng) {
246  using boost::variate_generator;
247  using boost::gamma_distribution;
248  variate_generator<RNG&, gamma_distribution<> >
249  gamma_rng(rng, gamma_distribution<>(alpha, beta));
250  return gamma_rng();
251  }
252 
253  }
254 }
255 
256 #endif

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