Stan  1.0
probability, sampling & optimization
inv_gamma.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
3 
4 #include <stan/agrad.hpp>
7 #include <stan/meta/traits.hpp>
9 #include <stan/prob/traits.hpp>
10 
11 namespace stan {
12 
13  namespace prob {
14 
31  template <bool propto,
32  typename T_y, typename T_shape, typename T_scale,
33  class Policy>
35  inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
36  const Policy&) {
37  static const char* function = "stan::prob::inv_gamma_log(%1%)";
38 
43  using boost::math::tools::promote_args;
46 
47  // check if any vectors are zero length
48  if (!(stan::length(y)
49  && stan::length(alpha)
50  && stan::length(beta)))
51  return 0.0;
52 
53  // set up return value accumulator
54  double logp(0.0);
55 
56  if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
57  return logp;
58  if (!check_finite(function, alpha, "Shape parameter",
59  &logp, Policy()))
60  return logp;
61  if (!check_positive(function, alpha, "Shape parameter",
62  &logp, Policy()))
63  return logp;
64  if (!check_finite(function, beta, "Scale parameter",
65  &logp, Policy()))
66  return logp;
67  if (!check_positive(function, beta, "Scale parameter",
68  &logp, Policy()))
69  return logp;
70  if (!(check_consistent_sizes(function,
71  y,alpha,beta,
72  "Random variable","Shape parameter","Scale parameter",
73  &logp, Policy())))
74  return logp;
75 
76  // check if no variables are involved and prop-to
78  return 0.0;
79 
80  // set up template expressions wrapping scalars into vector views
81  VectorView<const T_y> y_vec(y);
82  VectorView<const T_shape> alpha_vec(alpha);
83  VectorView<const T_scale> beta_vec(beta);
84 
85  for (size_t n = 0; n < length(y); n++) {
86  const double y_dbl = value_of(y_vec[n]);
87  if (y_dbl <= 0)
88  return LOG_ZERO;
89  }
90 
91  size_t N = max_size(y, alpha, beta);
92  agrad::OperandsAndPartials<T_y, T_shape, T_scale> operands_and_partials(y, alpha, beta);
93 
94  using boost::math::lgamma;
96  using boost::math::digamma;
97 
99  log_y(length(y));
101  inv_y(length(y));
102  for(size_t n = 0; n < length(y); n++) {
104  if (value_of(y_vec[n]) > 0)
105  log_y[n] = log(value_of(y_vec[n]));
107  inv_y[n] = 1.0 / value_of(y_vec[n]);
108  }
109 
111  lgamma_alpha(length(alpha));
113  digamma_alpha(length(alpha));
114  for (size_t n = 0; n < length(alpha); n++) {
116  lgamma_alpha[n] = lgamma(value_of(alpha_vec[n]));
118  digamma_alpha[n] = digamma(value_of(alpha_vec[n]));
119  }
120 
122  log_beta(length(beta));
124  for (size_t n = 0; n < length(beta); n++)
125  log_beta[n] = log(value_of(beta_vec[n]));
126 
127  for (size_t n = 0; n < N; n++) {
128  // pull out values of arguments
129  const double alpha_dbl = value_of(alpha_vec[n]);
130  const double beta_dbl = value_of(beta_vec[n]);
131 
133  logp -= lgamma_alpha[n];
135  logp += alpha_dbl * log_beta[n];
137  logp -= (alpha_dbl+1.0) * log_y[n];
139  logp -= beta_dbl * inv_y[n];
140 
141  // gradients
142  if (!is_constant<typename is_vector<T_y>::type>::value)
143  operands_and_partials.d_x1[n] += -(alpha_dbl+1) * inv_y[n] + beta_dbl * inv_y[n] * inv_y[n];
144  if (!is_constant<typename is_vector<T_shape>::type>::value)
145  operands_and_partials.d_x2[n] += -digamma_alpha[n] + log_beta[n] - log_y[n];
146  if (!is_constant<typename is_vector<T_scale>::type>::value)
147  operands_and_partials.d_x3[n] += alpha_dbl / beta_dbl - inv_y[n];
148  }
149  return operands_and_partials.to_var(logp);
150  }
151 
152  template <bool propto,
153  typename T_y, typename T_shape, typename T_scale>
154  inline
156  inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
157  return inv_gamma_log<propto>(y,alpha,beta,stan::math::default_policy());
158  }
159 
160  template <typename T_y, typename T_shape, typename T_scale,
161  class Policy>
162  inline
164  inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta,
165  const Policy&) {
166  return inv_gamma_log<false>(y,alpha,beta,Policy());
167  }
168 
169  template <typename T_y, typename T_shape, typename T_scale>
170  inline
172  inv_gamma_log(const T_y& y, const T_shape& alpha, const T_scale& beta) {
173  return inv_gamma_log<false>(y,alpha,beta,stan::math::default_policy());
174  }
175 
176 
177 
178  }
179 }
180 
181 #endif
double value_of(const agrad::var &v)
Return the value of the specified variable.
var lgamma(const stan::agrad::var &a)
The log gamma function for variables (C99).
var log(const var &a)
Return the natural log of the specified variable (cmath).
Definition: agrad.hpp:1730
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(T_a a, T_b b)
double value_of(T x)
Return the value of the specified scalar argument converted to a double value.
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
Checks if the variable y is nan.
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result, const Policy &)
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
bool check_finite(const char *function, const T_y &y, const char *name, T_result *result, const Policy &)
Checks if the variable y is finite.
boost::math::policies::policy default_policy
Default error-handling policy from Boost.
return_type< T_y, T_shape, T_scale >::type inv_gamma_log(const T_y &y, const T_shape &alpha, const T_scale &beta, const Policy &)
The log of an inverse gamma density for y with the specified shape and scale parameters.
Definition: inv_gamma.hpp:35
Probability, optimization and sampling library.
Definition: agrad.cpp:6
size_t length(const T &x)
Definition: traits.hpp:111
size_t max_size(const T1 &x1, const T2 &x2)
Definition: traits.hpp:148
A variable implementation that stores operands and derivatives with respect to the variable.
VectorView< double *, is_vector< T1 >::value > d_x1
VectorView< double *, is_vector< T2 >::value > d_x2
T_return_type to_var(double logp)
VectorView< double *, is_vector< T3 >::value > d_x3
Metaprogram to determine if a type has a base scalar type that can be assigned to type double.
Definition: traits.hpp:39
Metaprogramming struct to detect whether a given type is constant in the mathematical sense (not the ...
Definition: traits.hpp:25
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
Definition: traits.hpp:33
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:368

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