Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
chi_square.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__CHI_SQUARE_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__CHI_SQUARE_HPP__
3 
4 #include <boost/random/chi_squared_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 
37  template <bool propto,
38  typename T_y, typename T_dof,
39  class Policy>
40  typename return_type<T_y,T_dof>::type
41  chi_square_log(const T_y& y, const T_dof& nu, const Policy&) {
42  static const char* function = "stan::prob::chi_square_log(%1%)";
43 
44  // check if any vectors are zero length
45  if (!(stan::length(y)
46  && stan::length(nu)))
47  return 0.0;
48 
54 
55  double logp(0.0);
56  if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
57  return logp;
58  if (!check_finite(function, nu, "Degrees of freedom parameter", &logp, Policy()))
59  return logp;
60  if (!check_positive(function, nu, "Degrees of freedom parameter", &logp, Policy()))
61  return logp;
62 
63  if (!(check_consistent_sizes(function,
64  y,nu,
65  "Random variable","Degrees of freedom parameter",
66  &logp, Policy())))
67  return logp;
68 
69 
70  // set up template expressions wrapping scalars into vector views
71  VectorView<const T_y> y_vec(y);
72  VectorView<const T_dof> nu_vec(nu);
73  size_t N = max_size(y, nu);
74 
75  for (size_t n = 0; n < length(y); n++)
76  if (value_of(y_vec[n]) < 0)
77  return LOG_ZERO;
78 
79  // check if no variables are involved and prop-to
81  return 0.0;
82 
83  using boost::math::digamma;
84  using boost::math::lgamma;
86 
88  is_vector<T_y>::value> log_y(length(y));
89  for (size_t i = 0; i < length(y); i++)
91  log_y[i] = log(value_of(y_vec[i]));
92 
94  is_vector<T_y>::value> inv_y(length(y));
95  for (size_t i = 0; i < length(y); i++)
97  inv_y[i] = 1.0 / value_of(y_vec[i]);
98 
100  is_vector<T_dof>::value> lgamma_half_nu(length(nu));
102  is_vector<T_dof>::value> digamma_half_nu_over_two(length(nu));
103 
104  for (size_t i = 0; i < length(nu); i++) {
105  double half_nu = 0.5 * value_of(nu_vec[i]);
107  lgamma_half_nu[i] = lgamma(half_nu);
109  digamma_half_nu_over_two[i] = digamma(half_nu) * 0.5;
110  }
111 
112 
113  agrad::OperandsAndPartials<T_y,T_dof> operands_and_partials(y, nu);
114 
115  for (size_t n = 0; n < N; n++) {
116  const double y_dbl = value_of(y_vec[n]);
117  const double half_y = 0.5 * y_dbl;
118  const double nu_dbl = value_of(nu_vec[n]);
119  const double half_nu = 0.5 * nu_dbl;
121  logp += nu_dbl * NEG_LOG_TWO_OVER_TWO - lgamma_half_nu[n];
123  logp += (half_nu-1.0) * log_y[n];
125  logp -= half_y;
126 
128  operands_and_partials.d_x1[n] += (half_nu-1.0)*inv_y[n] - 0.5;
129  }
131  operands_and_partials.d_x2[n]
132  += NEG_LOG_TWO_OVER_TWO - digamma_half_nu_over_two[n] + log_y[n]*0.5;
133  }
134  }
135  return operands_and_partials.to_var(logp);
136  }
137 
138 
139  template <bool propto,
140  typename T_y, typename T_dof>
141  inline
143  chi_square_log(const T_y& y, const T_dof& nu) {
144  return chi_square_log<propto>(y,nu,stan::math::default_policy());
145  }
146 
147 
148  template <typename T_y, typename T_dof,
149  class Policy>
150  inline
152  chi_square_log(const T_y& y, const T_dof& nu, const Policy&) {
153  return chi_square_log<false>(y,nu,Policy());
154  }
155 
156 
157  template <typename T_y, typename T_dof>
158  inline
160  chi_square_log(const T_y& y, const T_dof& nu) {
161  return chi_square_log<false>(y,nu,stan::math::default_policy());
162  }
163 
173  /*template <typename T_y, typename T_dof,
174  class Policy>
175  typename return_type<T_y,T_dof>::type
176  chi_square_cdf(const T_y& y, const T_dof& nu, const Policy&) {
177  static const char* function = "stan::prob::chi_square_cdf(%1%)";
178 
179  using stan::math::check_positive;
180  using stan::math::check_finite;
181  using stan::math::check_not_nan;
182  using return_type;
183 
184  typename return_type<T_y,T_dof>::type lp;
185  if (!check_not_nan(function, y, "Random variable", &lp, Policy()))
186  return lp;
187  if (!check_finite(function, nu, "Degrees of freedom parameter", &lp, Policy()))
188  return lp;
189  if (!check_positive(function, nu, "Degrees of freedom parameter", &lp, Policy()))
190  return lp;
191 
192  // FIXME: include when gamma_cdf() is ready
193  return stan::prob::gamma_cdf(y,nu/2,0.5,Policy());
194  }
195 
196  template <typename T_y, typename T_dof>
197  typename return_type<T_y,T_dof>::type
198  chi_square_cdf(const T_y& y, const T_dof& nu) {
199  return chi_square_cdf(y, nu, stan::math::default_policy());
200  }*/
201 
202  template <class RNG>
203  inline double
204  chi_square_rng(const double nu,
205  RNG& rng) {
206  using boost::variate_generator;
207  using boost::random::chi_squared_distribution;
208  variate_generator<RNG&, chi_squared_distribution<> >
209  chi_square_rng(rng, chi_squared_distribution<>(nu));
210  return chi_square_rng();
211  }
212  }
213 }
214 
215 #endif
216 

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