Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
frechet.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__FRECHET_HPP
2 #define STAN__PROB__DISTRIBUTIONS__FRECHET_HPP
3 
4 #include <boost/random/weibull_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
11 #include <stan/meta/traits.hpp>
12 #include <stan/prob/constants.hpp>
13 #include <stan/prob/traits.hpp>
14 
15 namespace stan {
16 
17  namespace prob {
18 
19  // Frechet(y|alpha,sigma) [y > 0; alpha > 0; sigma > 0]
20  // FIXME: document
21  template <bool propto,
22  typename T_y, typename T_shape, typename T_scale>
23  typename return_type<T_y,T_shape,T_scale>::type
24  frechet_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
25  static const char* function = "stan::prob::frechet_log(%1%)";
26 
33 
34  // check if any vectors are zero length
35  if (!(stan::length(y)
36  && stan::length(alpha)
37  && stan::length(sigma)))
38  return 0.0;
39 
40  // set up return value accumulator
41  double logp(0.0);
42  check_positive(function, y, "Random variable", &logp);
43  check_positive_finite(function, alpha, "Shape parameter", &logp);
44  check_positive_finite(function, sigma, "Scale parameter", &logp);
45  check_consistent_sizes(function,
46  y,alpha,sigma,
47  "Random variable","Shape parameter",
48  "Scale parameter",
49  &logp);
50 
51  // check if no variables are involved and prop-to
53  return 0.0;
54 
55  VectorView<const T_y> y_vec(y);
56  VectorView<const T_shape> alpha_vec(alpha);
57  VectorView<const T_scale> sigma_vec(sigma);
58  size_t N = max_size(y, alpha, sigma);
59 
61  is_vector<T_shape>::value> log_alpha(length(alpha));
62  for (size_t i = 0; i < length(alpha); i++)
64  log_alpha[i] = log(value_of(alpha_vec[i]));
65 
67  is_vector<T_y>::value> log_y(length(y));
68  for (size_t i = 0; i < length(y); i++)
70  log_y[i] = log(value_of(y_vec[i]));
71 
73  is_vector<T_scale>::value> log_sigma(length(sigma));
74  for (size_t i = 0; i < length(sigma); i++)
76  log_sigma[i] = log(value_of(sigma_vec[i]));
77 
79  is_vector<T_y>::value> inv_y(length(y));
80  for (size_t i = 0; i < length(y); i++)
82  inv_y[i] = 1.0 / value_of(y_vec[i]);
83 
86  sigma_div_y_pow_alpha(N);
87  for (size_t i = 0; i < N; i++)
89  const double alpha_dbl = value_of(alpha_vec[i]);
90  sigma_div_y_pow_alpha[i] = pow(value_of(inv_y[i]) * value_of(sigma_vec[i]), alpha_dbl);
91  }
92 
93  agrad::OperandsAndPartials<T_y,T_shape,T_scale> operands_and_partials(y,alpha,sigma);
94  for (size_t n = 0; n < N; n++) {
95  const double alpha_dbl = value_of(alpha_vec[n]);
97  logp += log_alpha[n];
99  logp -= (alpha_dbl+1.0)*log_y[n];
101  logp += alpha_dbl*log_sigma[n];
103  logp -= sigma_div_y_pow_alpha[n];
104 
106  const double inv_y_dbl = value_of(inv_y[n]);
107  operands_and_partials.d_x1[n]
108  += -(alpha_dbl+1.0) * inv_y_dbl
109  + alpha_dbl * sigma_div_y_pow_alpha[n] * inv_y_dbl;
110  }
112  operands_and_partials.d_x2[n]
113  += 1.0/alpha_dbl
114  + (1.0 - sigma_div_y_pow_alpha[n]) * (log_sigma[n] - log_y[n]);
116  operands_and_partials.d_x3[n]
117  += alpha_dbl / value_of(sigma_vec[n]) * (1 - sigma_div_y_pow_alpha[n]);
118  }
119  return operands_and_partials.to_var(logp);
120  }
121 
122  template <typename T_y, typename T_shape, typename T_scale>
123  inline
125  frechet_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
126  return frechet_log<false>(y,alpha,sigma);
127  }
128 
129  template <typename T_y, typename T_shape, typename T_scale>
131  frechet_cdf(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
132 
133  static const char* function = "stan::prob::frechet_cdf(%1%)";
134 
138  using boost::math::tools::promote_args;
139  using stan::math::value_of;
140 
141  // check if any vectors are zero length
142  if (!(stan::length(y)
143  && stan::length(alpha)
144  && stan::length(sigma)))
145  return 1.0;
146 
147  double cdf(1.0);
148  check_positive(function, y, "Random variable", &cdf);
149  check_positive_finite(function, alpha, "Shape parameter", &cdf);
150  check_positive_finite(function, sigma, "Scale parameter", &cdf);
151 
153  operands_and_partials(y, alpha, sigma);
154 
155  VectorView<const T_y> y_vec(y);
156  VectorView<const T_scale> sigma_vec(sigma);
157  VectorView<const T_shape> alpha_vec(alpha);
158  size_t N = max_size(y, sigma, alpha);
159  for (size_t n = 0; n < N; n++) {
160  const double y_dbl = value_of(y_vec[n]);
161  const double sigma_dbl = value_of(sigma_vec[n]);
162  const double alpha_dbl = value_of(alpha_vec[n]);
163  const double pow_ = pow(sigma_dbl / y_dbl, alpha_dbl);
164  const double cdf_ = exp(-pow_);
165 
166  //cdf
167  cdf *= cdf_;
168 
169  //gradients
171  operands_and_partials.d_x1[n] += pow_ * alpha_dbl / y_dbl;
173  operands_and_partials.d_x2[n] += pow_ * log(y_dbl / sigma_dbl);
175  operands_and_partials.d_x3[n] -= pow_ * alpha_dbl / sigma_dbl;
176  }
177 
179  for (size_t n = 0; n < stan::length(y); ++n)
180  operands_and_partials.d_x1[n] *= cdf;
182  for (size_t n = 0; n < stan::length(alpha); ++n)
183  operands_and_partials.d_x2[n] *= cdf;
185  for (size_t n = 0; n < stan::length(sigma); ++n)
186  operands_and_partials.d_x3[n] *= cdf;
187 
188  return operands_and_partials.to_var(cdf);
189  }
190 
191  template <typename T_y, typename T_shape, typename T_scale>
193  frechet_cdf_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
194 
195  static const char* function = "stan::prob::frechet_cdf_log(%1%)";
196 
200  using boost::math::tools::promote_args;
201  using stan::math::value_of;
202 
203  // check if any vectors are zero length
204  if (!(stan::length(y)
205  && stan::length(alpha)
206  && stan::length(sigma)))
207  return 0.0;
208 
209  double cdf_log(0.0);
210  check_positive(function, y, "Random variable", &cdf_log);
211  check_positive_finite(function, alpha, "Shape parameter", &cdf_log);
212  check_positive_finite(function, sigma, "Scale parameter", &cdf_log);
213 
215  operands_and_partials(y, alpha, sigma);
216 
217  VectorView<const T_y> y_vec(y);
218  VectorView<const T_scale> sigma_vec(sigma);
219  VectorView<const T_shape> alpha_vec(alpha);
220  size_t N = max_size(y, sigma, alpha);
221  for (size_t n = 0; n < N; n++) {
222  const double y_dbl = value_of(y_vec[n]);
223  const double sigma_dbl = value_of(sigma_vec[n]);
224  const double alpha_dbl = value_of(alpha_vec[n]);
225  const double pow_ = pow(sigma_dbl / y_dbl, alpha_dbl);
226 
227  //cdf_log
228  cdf_log -= pow_;
229 
230  //gradients
232  operands_and_partials.d_x1[n] += pow_ * alpha_dbl / y_dbl;
234  operands_and_partials.d_x2[n] += pow_ * log(y_dbl / sigma_dbl);
236  operands_and_partials.d_x3[n] -= pow_ * alpha_dbl / sigma_dbl;
237  }
238 
239  return operands_and_partials.to_var(cdf_log);
240  }
241 
242  template <typename T_y, typename T_shape, typename T_scale>
244  frechet_ccdf_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
245 
246  static const char* function = "stan::prob::frechet_ccdf_log(%1%)";
247 
251  using boost::math::tools::promote_args;
252  using stan::math::value_of;
253 
254  // check if any vectors are zero length
255  if (!(stan::length(y)
256  && stan::length(alpha)
257  && stan::length(sigma)))
258  return 0.0;
259 
260  double ccdf_log(0.0);
261  check_positive(function, y, "Random variable", &ccdf_log);
262  check_positive_finite(function, alpha, "Shape parameter", &ccdf_log);
263  check_positive_finite(function, sigma, "Scale parameter", &ccdf_log);
264 
266  operands_and_partials(y, alpha, sigma);
267 
268  VectorView<const T_y> y_vec(y);
269  VectorView<const T_scale> sigma_vec(sigma);
270  VectorView<const T_shape> alpha_vec(alpha);
271  size_t N = max_size(y, sigma, alpha);
272  for (size_t n = 0; n < N; n++) {
273  const double y_dbl = value_of(y_vec[n]);
274  const double sigma_dbl = value_of(sigma_vec[n]);
275  const double alpha_dbl = value_of(alpha_vec[n]);
276  const double pow_ = pow(sigma_dbl / y_dbl, alpha_dbl);
277  const double exp_ = exp(-pow_);
278 
279  //ccdf_log
280  ccdf_log += log(1 - exp_);
281 
282  //gradients
283  const double rep_deriv_ = pow_ / ( 1.0 / exp_ - 1 );
285  operands_and_partials.d_x1[n] -= alpha_dbl / y_dbl * rep_deriv_;
287  operands_and_partials.d_x2[n] -= log(y_dbl / sigma_dbl) * rep_deriv_;
289  operands_and_partials.d_x3[n] += alpha_dbl / sigma_dbl * rep_deriv_;
290  }
291 
292  return operands_and_partials.to_var(ccdf_log);
293  }
294 
295  template <class RNG>
296  inline double
297  frechet_rng(const double alpha,
298  const double sigma,
299  RNG& rng) {
300  using boost::variate_generator;
301  using boost::random::weibull_distribution;
302 
303  static const char* function = "stan::prob::frechet_rng(%1%)";
304 
308 
309  check_finite(function, alpha, "Shape parameter", (double*)0);
310  check_positive(function, alpha, "Shape parameter", (double*)0);
311  check_not_nan(function, sigma, "Scale parameter", (double*)0);
312  check_positive(function, sigma, "Scale parameter", (double*)0);
313 
314  variate_generator<RNG&, weibull_distribution<> >
315  weibull_rng(rng, weibull_distribution<>(alpha, 1.0/sigma));
316  return 1.0 / weibull_rng();
317  }
318  }
319 }
320 #endif
double weibull_rng(const double alpha, const double sigma, RNG &rng)
Definition: weibull.hpp:304
return_type< T_y, T_shape, T_scale >::type frechet_ccdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: frechet.hpp:244
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
fvar< T > pow(const fvar< T > &x1, const fvar< T > &x2)
Definition: pow.hpp:17
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(const T_a a, const T_b b)
Calculated the value of the first argument times log of the second argument while behaving properly w...
size_t length(const T &)
Definition: traits.hpp:159
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
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
return_type< T_y, T_shape, T_scale >::type frechet_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: frechet.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
bool check_nonnegative(const char *function, const T_y &y, const char *name, T_result *result)
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_positive(const char *function, const T_y &y, const char *name, T_result *result)
return_type< T_y, T_shape, T_scale >::type frechet_cdf(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: frechet.hpp:131
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
double frechet_rng(const double alpha, const double sigma, RNG &rng)
Definition: frechet.hpp:297
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
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 > exp(const fvar< T > &x)
Definition: exp.hpp:16
return_type< T_y, T_shape, T_scale >::type frechet_cdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: frechet.hpp:193

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