Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
pareto.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__PARETO_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__PARETO_HPP__
3 
4 #include <boost/random/exponential_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 
15 namespace stan {
16  namespace prob {
17 
18  // Pareto(y|y_m,alpha) [y > y_m; y_m > 0; alpha > 0]
19  template <bool propto,
20  typename T_y, typename T_scale, typename T_shape,
21  class Policy>
22  typename return_type<T_y,T_scale,T_shape>::type
23  pareto_log(const T_y& y, const T_scale& y_min, const T_shape& alpha,
24  const Policy&) {
25  static const char* function = "stan::prob::pareto_log(%1%)";
26 
32 
33 
34  // check if any vectors are zero length
35  if (!(stan::length(y)
36  && stan::length(y_min)
37  && stan::length(alpha)))
38  return 0.0;
39 
40  // set up return value accumulator
41  double logp(0.0);
42 
43  // validate args (here done over var, which should be OK)
44  if (!check_not_nan(function, y, "Random variable", &logp, Policy()))
45  return logp;
46  if (!check_finite(function, y_min, "Scale parameter",
47  &logp, Policy()))
48  return logp;
49  if (!check_positive(function, y_min, "Scale parameter",
50  &logp, Policy()))
51  return logp;
52  if (!check_finite(function, alpha, "Shape parameter",
53  &logp, Policy()))
54  return logp;
55  if (!check_positive(function, alpha, "Shape parameter",
56  &logp, Policy()))
57  return logp;
58  if (!(check_consistent_sizes(function,
59  y,y_min,alpha,
60  "Random variable","Scale parameter","Shape parameter",
61  &logp, Policy())))
62  return logp;
63 
64  // check if no variables are involved and prop-to
66  return 0.0;
67 
68  VectorView<const T_y> y_vec(y);
69  VectorView<const T_scale> y_min_vec(y_min);
70  VectorView<const T_shape> alpha_vec(alpha);
71  size_t N = max_size(y, y_min, alpha);
72 
73  for (size_t n = 0; n < N; n++) {
74  if (y_vec[n] < y_min_vec[n])
75  return LOG_ZERO;
76  }
77 
78  // set up template expressions wrapping scalars into vector views
79  agrad::OperandsAndPartials<T_y,T_scale,T_shape> operands_and_partials(y, y_min, alpha);
80 
83  for (size_t n = 0; n < length(y); n++)
84  log_y[n] = log(value_of(y_vec[n]));
87  for (size_t n = 0; n < length(y); n++)
88  inv_y[n] = 1 / value_of(y_vec[n]);
90  log_y_min(length(y_min));
92  for (size_t n = 0; n < length(y_min); n++)
93  log_y_min[n] = log(value_of(y_min_vec[n]));
96  for (size_t n = 0; n < length(alpha); n++)
97  log_alpha[n] = log(value_of(alpha_vec[n]));
98 
101  for (size_t n = 0; n < length(alpha); n++)
102  inv_alpha[n] = 1 / value_of(alpha_vec[n]);
103 
105 
106  for (size_t n = 0; n < N; n++) {
107  const double alpha_dbl = value_of(alpha_vec[n]);
108  // log probability
110  logp += log_alpha[n];
112  logp += alpha_dbl * log_y_min[n];
114  logp -= alpha_dbl * log_y[n] + log_y[n];
115 
116  // gradients
118  operands_and_partials.d_x1[n] -= alpha_dbl * inv_y[n] + inv_y[n];
120  operands_and_partials.d_x2[n] += alpha_dbl / value_of(y_min_vec[n]);
122  operands_and_partials.d_x3[n] += 1 / alpha_dbl + log_y_min[n] - log_y[n];
123  }
124  return operands_and_partials.to_var(logp);
125  }
126 
127 
128  template <bool propto,
129  typename T_y, typename T_scale, typename T_shape>
130  inline
132  pareto_log(const T_y& y, const T_scale& y_min, const T_shape& alpha) {
133  return pareto_log<propto>(y,y_min,alpha,stan::math::default_policy());
134  }
135 
136  template <typename T_y, typename T_scale, typename T_shape,
137  class Policy>
138  inline
140  pareto_log(const T_y& y, const T_scale& y_min, const T_shape& alpha,
141  const Policy&) {
142  return pareto_log<false>(y,y_min,alpha,Policy());
143  }
144 
145  template <typename T_y, typename T_scale, typename T_shape>
146  inline
148  pareto_log(const T_y& y, const T_scale& y_min, const T_shape& alpha) {
149  return pareto_log<false>(y,y_min,alpha,stan::math::default_policy());
150  }
151 
152  template <typename T_y, typename T_scale, typename T_shape, class Policy>
154  pareto_cdf(const T_y& y, const T_scale& y_min, const T_shape& alpha, const Policy&) {
155 
156  // Check sizes
157  // Size checks
158  if ( !( stan::length(y) && stan::length(y_min) && stan::length(alpha) ) ) return 1.0;
159 
160  // Check errors
161  static const char* function = "stan::prob::pareto_cdf(%1%)";
162 
169 
170  using stan::math::value_of;
171 
172  double P(1.0);
173 
174  if (!check_not_nan(function, y, "Random variable", &P, Policy()))
175  return P;
176 
177  if (!check_nonnegative(function, y, "Random variable", &P, Policy()))
178  return P;
179 
180  if (!check_finite(function, y_min, "Scale parameter", &P, Policy()))
181  return P;
182 
183  if (!check_positive(function, y_min, "Scale parameter", &P, Policy()))
184  return P;
185 
186  if (!check_finite(function, alpha, "Shape parameter", &P, Policy()))
187  return P;
188 
189  if (!check_positive(function, alpha, "Shape parameter", &P, Policy()))
190  return P;
191 
192  if (!(check_consistent_sizes(function, y, y_min, alpha,
193  "Random variable", "Scale parameter", "Shape parameter",
194  &P, Policy())))
195  return P;
196 
197  // Wrap arguments in vectors
198  VectorView<const T_y> y_vec(y);
199  VectorView<const T_scale> y_min_vec(y_min);
200  VectorView<const T_shape> alpha_vec(alpha);
201  size_t N = max_size(y, y_min, alpha);
202 
203  agrad::OperandsAndPartials<T_y, T_scale, T_shape> operands_and_partials(y, y_min, alpha);
204 
205  std::fill(operands_and_partials.all_partials,
206  operands_and_partials.all_partials + operands_and_partials.nvaris, 0.0);
207 
208  // Explicit return for extreme values
209  // The gradients are technically ill-defined, but treated as zero
210 
211  for (size_t i = 0; i < stan::length(y); i++) {
212  if (value_of(y_vec[i]) < value_of(y_min_vec[i]))
213  return operands_and_partials.to_var(0.0);
214  }
215 
216  // Compute vectorized CDF and its gradients
217 
218  for (size_t n = 0; n < N; n++) {
219 
220  // Explicit results for extreme values
221  // The gradients are technically ill-defined, but treated as zero
222  if (value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
223  continue;
224  }
225 
226  // Pull out values
227  const double log_dbl = log( value_of(y_min_vec[n]) / value_of(y_vec[n]) );
228  const double y_min_inv_dbl = 1.0 / value_of(y_min_vec[n]);
229  const double alpha_dbl = value_of(alpha_vec[n]);
230 
231  // Compute
232  const double Pn = 1.0 - exp( alpha_dbl * log_dbl );
233 
234  P *= Pn;
235 
237  operands_and_partials.d_x1[n]
238  += alpha_dbl * y_min_inv_dbl * exp( (alpha_dbl + 1) * log_dbl ) / Pn;
239 
241  operands_and_partials.d_x2[n]
242  += - alpha_dbl * y_min_inv_dbl * exp( alpha_dbl * log_dbl ) / Pn;
243 
245  operands_and_partials.d_x3[n]
246  += - exp( alpha_dbl * log_dbl ) * log_dbl / Pn;
247 
248  }
249 
250 
252  for(size_t n = 0; n < stan::length(y); ++n) operands_and_partials.d_x1[n] *= P;
253  }
254 
256  for(size_t n = 0; n < stan::length(y_min); ++n) operands_and_partials.d_x2[n] *= P;
257  }
258 
260  for(size_t n = 0; n < stan::length(alpha); ++n) operands_and_partials.d_x3[n] *= P;
261  }
262 
263  return operands_and_partials.to_var(P);
264 
265  }
266 
267  template <typename T_y, typename T_scale, typename T_shape>
269  pareto_cdf(const T_y& y, const T_scale& y_min, const T_shape& alpha) {
270  return pareto_cdf(y, y_min, alpha, stan::math::default_policy());
271  }
272 
273  template <class RNG>
274  inline double
275  pareto_rng(const double y_min,
276  const double alpha,
277  RNG& rng) {
278  using boost::variate_generator;
279  using boost::exponential_distribution;
280  variate_generator<RNG&, exponential_distribution<> >
281  exp_rng(rng, exponential_distribution<>(alpha));
282  return y_min * std::exp(exp_rng());
283  }
284  }
285 }
286 #endif

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