Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
weibull.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__WEIBULL_HPP
2 #define STAN__PROB__DISTRIBUTIONS__WEIBULL_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  // Weibull(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  weibull_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
25  static const char* function = "stan::prob::weibull_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_finite(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 
60  for (size_t n = 0; n < N; n++) {
61  const double y_dbl = value_of(y_vec[n]);
62  if (y_dbl < 0)
63  return LOG_ZERO;
64  }
65 
67  is_vector<T_shape>::value> log_alpha(length(alpha));
68  for (size_t i = 0; i < length(alpha); i++)
70  log_alpha[i] = log(value_of(alpha_vec[i]));
71 
73  is_vector<T_y>::value> log_y(length(y));
74  for (size_t i = 0; i < length(y); i++)
76  log_y[i] = log(value_of(y_vec[i]));
77 
79  is_vector<T_scale>::value> log_sigma(length(sigma));
80  for (size_t i = 0; i < length(sigma); i++)
82  log_sigma[i] = log(value_of(sigma_vec[i]));
83 
85  is_vector<T_scale>::value> inv_sigma(length(sigma));
86  for (size_t i = 0; i < length(sigma); i++)
88  inv_sigma[i] = 1.0 / value_of(sigma_vec[i]);
89 
92  y_div_sigma_pow_alpha(N);
93  for (size_t i = 0; i < N; i++)
95  const double y_dbl = value_of(y_vec[i]);
96  const double alpha_dbl = value_of(alpha_vec[i]);
97  y_div_sigma_pow_alpha[i] = pow(y_dbl * inv_sigma[i], alpha_dbl);
98  }
99 
100  agrad::OperandsAndPartials<T_y,T_shape,T_scale> operands_and_partials(y,alpha,sigma);
101  for (size_t n = 0; n < N; n++) {
102  const double alpha_dbl = value_of(alpha_vec[n]);
104  logp += log_alpha[n];
106  logp += (alpha_dbl-1.0)*log_y[n];
108  logp -= alpha_dbl*log_sigma[n];
110  logp -= y_div_sigma_pow_alpha[n];
111 
113  const double inv_y = 1.0 / value_of(y_vec[n]);
114  operands_and_partials.d_x1[n]
115  += (alpha_dbl-1.0) * inv_y
116  - alpha_dbl * y_div_sigma_pow_alpha[n] * inv_y;
117  }
119  operands_and_partials.d_x2[n]
120  += 1.0/alpha_dbl
121  + (1.0 - y_div_sigma_pow_alpha[n]) * (log_y[n] - log_sigma[n]);
123  operands_and_partials.d_x3[n]
124  += alpha_dbl * inv_sigma[n] * ( y_div_sigma_pow_alpha[n] - 1.0 );
125  }
126  return operands_and_partials.to_var(logp);
127  }
128 
129  template <typename T_y, typename T_shape, typename T_scale>
130  inline
132  weibull_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
133  return weibull_log<false>(y,alpha,sigma);
134  }
135 
136  template <typename T_y, typename T_shape, typename T_scale>
138  weibull_cdf(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
139 
140  static const char* function = "stan::prob::weibull_cdf(%1%)";
141 
144  using boost::math::tools::promote_args;
145  using stan::math::value_of;
146 
147  // check if any vectors are zero length
148  if (!(stan::length(y)
149  && stan::length(alpha)
150  && stan::length(sigma)))
151  return 1.0;
152 
153  double cdf(1.0);
154  check_nonnegative(function, y, "Random variable", &cdf);
155  check_positive_finite(function, alpha, "Shape parameter", &cdf);
156  check_positive_finite(function, sigma, "Scale parameter", &cdf);
157 
159  operands_and_partials(y, alpha, sigma);
160 
161  VectorView<const T_y> y_vec(y);
162  VectorView<const T_scale> sigma_vec(sigma);
163  VectorView<const T_shape> alpha_vec(alpha);
164  size_t N = max_size(y, sigma, alpha);
165  for (size_t n = 0; n < N; n++) {
166  const double y_dbl = value_of(y_vec[n]);
167  const double sigma_dbl = value_of(sigma_vec[n]);
168  const double alpha_dbl = value_of(alpha_vec[n]);
169  const double pow_ = pow(y_dbl / sigma_dbl, alpha_dbl);
170  const double exp_ = exp(-pow_);
171  const double cdf_ = 1.0 - exp_;
172 
173  //cdf
174  cdf *= cdf_;
175 
176  //gradients
177  const double rep_deriv = exp_ * pow_ / cdf_;
179  operands_and_partials.d_x1[n] += rep_deriv * alpha_dbl / y_dbl;
181  operands_and_partials.d_x2[n] += rep_deriv * log(y_dbl / sigma_dbl);
183  operands_and_partials.d_x3[n] -= rep_deriv * alpha_dbl / sigma_dbl;
184  }
185 
187  for (size_t n = 0; n < stan::length(y); ++n)
188  operands_and_partials.d_x1[n] *= cdf;
190  for (size_t n = 0; n < stan::length(alpha); ++n)
191  operands_and_partials.d_x2[n] *= cdf;
193  for (size_t n = 0; n < stan::length(sigma); ++n)
194  operands_and_partials.d_x3[n] *= cdf;
195 
196  return operands_and_partials.to_var(cdf);
197  }
198 
199  template <typename T_y, typename T_shape, typename T_scale>
201  weibull_cdf_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
202 
203  static const char* function = "stan::prob::weibull_cdf_log(%1%)";
204 
207  using boost::math::tools::promote_args;
208  using stan::math::value_of;
209 
210  // check if any vectors are zero length
211  if (!(stan::length(y)
212  && stan::length(alpha)
213  && stan::length(sigma)))
214  return 0.0;
215 
216  double cdf_log(0.0);
217  check_nonnegative(function, y, "Random variable", &cdf_log);
218  check_positive_finite(function, alpha, "Shape parameter", &cdf_log);
219  check_positive_finite(function, sigma, "Scale parameter", &cdf_log);
220 
222  operands_and_partials(y, alpha, sigma);
223 
224  VectorView<const T_y> y_vec(y);
225  VectorView<const T_scale> sigma_vec(sigma);
226  VectorView<const T_shape> alpha_vec(alpha);
227  size_t N = max_size(y, sigma, alpha);
228  for (size_t n = 0; n < N; n++) {
229  const double y_dbl = value_of(y_vec[n]);
230  const double sigma_dbl = value_of(sigma_vec[n]);
231  const double alpha_dbl = value_of(alpha_vec[n]);
232  const double pow_ = pow(y_dbl / sigma_dbl, alpha_dbl);
233  const double exp_ = exp(-pow_);
234  const double cdf_ = 1.0 - exp_;
235 
236  //cdf_log
237  cdf_log += log(cdf_);
238 
239  //gradients
240  const double rep_deriv = pow_ / (1.0 / exp_ - 1.0);
242  operands_and_partials.d_x1[n] += rep_deriv * alpha_dbl / y_dbl;
244  operands_and_partials.d_x2[n] += rep_deriv * log(y_dbl / sigma_dbl);
246  operands_and_partials.d_x3[n] -= rep_deriv * alpha_dbl / sigma_dbl;
247  }
248 
249  return operands_and_partials.to_var(cdf_log);
250  }
251 
252  template <typename T_y, typename T_shape, typename T_scale>
254  weibull_ccdf_log(const T_y& y, const T_shape& alpha, const T_scale& sigma) {
255 
256  static const char* function = "stan::prob::weibull_ccdf_log(%1%)";
257 
260  using boost::math::tools::promote_args;
261  using stan::math::value_of;
262 
263  // check if any vectors are zero length
264  if (!(stan::length(y)
265  && stan::length(alpha)
266  && stan::length(sigma)))
267  return 0.0;
268 
269  double ccdf_log(0.0);
270  check_nonnegative(function, y, "Random variable", &ccdf_log);
271  check_positive_finite(function, alpha, "Shape parameter", &ccdf_log);
272  check_positive_finite(function, sigma, "Scale parameter", &ccdf_log);
273 
275  operands_and_partials(y, alpha, sigma);
276 
277  VectorView<const T_y> y_vec(y);
278  VectorView<const T_scale> sigma_vec(sigma);
279  VectorView<const T_shape> alpha_vec(alpha);
280  size_t N = max_size(y, sigma, alpha);
281  for (size_t n = 0; n < N; n++) {
282  const double y_dbl = value_of(y_vec[n]);
283  const double sigma_dbl = value_of(sigma_vec[n]);
284  const double alpha_dbl = value_of(alpha_vec[n]);
285  const double pow_ = pow(y_dbl / sigma_dbl, alpha_dbl);
286 
287  //ccdf_log
288  ccdf_log -= pow_;
289 
290  //gradients
292  operands_and_partials.d_x1[n] -= alpha_dbl / y_dbl * pow_;
294  operands_and_partials.d_x2[n] -= log(y_dbl / sigma_dbl) * pow_;
296  operands_and_partials.d_x3[n] += alpha_dbl / sigma_dbl * pow_;
297  }
298 
299  return operands_and_partials.to_var(ccdf_log);
300  }
301 
302  template <class RNG>
303  inline double
304  weibull_rng(const double alpha,
305  const double sigma,
306  RNG& rng) {
307  using boost::variate_generator;
308  using boost::random::weibull_distribution;
309 
310  static const char* function = "stan::prob::weibull_rng(%1%)";
311 
313 
314  check_positive_finite(function, alpha, "Shape parameter", (double*)0);
315  check_positive_finite(function, sigma, "Scale parameter", (double*)0);
316 
317  variate_generator<RNG&, weibull_distribution<> >
318  weibull_rng(rng, weibull_distribution<>(alpha, sigma));
319  return weibull_rng();
320  }
321  }
322 }
323 #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 weibull_cdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: weibull.hpp:201
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
return_type< T_y, T_shape, T_scale >::type weibull_cdf(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: weibull.hpp:138
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...
return_type< T_y, T_shape, T_scale >::type weibull_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: weibull.hpp:24
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
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
return_type< T_y, T_shape, T_scale >::type weibull_ccdf_log(const T_y &y, const T_shape &alpha, const T_scale &sigma)
Definition: weibull.hpp:254
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_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
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

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