Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gumbel.hpp
Go to the documentation of this file.
1 #ifndef STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__GUMBEL_HPP
2 #define STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__GUMBEL_HPP
3 
4 #include <boost/random/uniform_01.hpp>
5 #include <boost/random/variate_generator.hpp>
6 
9 #include <stan/meta/traits.hpp>
10 #include <stan/prob/constants.hpp>
11 #include <stan/prob/traits.hpp>
14 
15 namespace stan {
16 
17  namespace prob {
18 
19  template <bool propto, typename T_y, typename T_loc, typename T_scale>
20  typename return_type<T_y,T_loc,T_scale>::type
21  gumbel_log(const T_y& y, const T_loc& mu, const T_scale& beta) {
22  static const char* function = "stan::prob::gumbel_log(%1%)";
23 
24  using std::log;
25  using std::exp;
33 
34  // check if any vectors are zero length
35  if (!(stan::length(y)
36  && stan::length(mu)
37  && stan::length(beta)))
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  check_not_nan(function, y, "Random variable", &logp);
45  check_finite(function, mu, "Location parameter", &logp);
46  check_positive(function, beta, "Scale parameter", &logp);
47  check_consistent_sizes(function,
48  y,mu,beta,
49  "Random variable","Location parameter",
50  "Scale parameter",
51  &logp);
52 
53  // check if no variables are involved and prop-to
55  return 0.0;
56 
57  // set up template expressions wrapping scalars into vector views
59  operands_and_partials(y, mu, beta);
60 
61  VectorView<const T_y> y_vec(y);
62  VectorView<const T_loc> mu_vec(mu);
63  VectorView<const T_scale> beta_vec(beta);
64  size_t N = max_size(y, mu, beta);
65 
68  is_vector<T_scale>::value> log_beta(length(beta));
69  for (size_t i = 0; i < length(beta); i++) {
70  inv_beta[i] = 1.0 / value_of(beta_vec[i]);
72  log_beta[i] = log(value_of(beta_vec[i]));
73  }
74 
75  for (size_t n = 0; n < N; n++) {
76  // pull out values of arguments
77  const double y_dbl = value_of(y_vec[n]);
78  const double mu_dbl = value_of(mu_vec[n]);
79 
80  // reusable subexpression values
81  const double y_minus_mu_over_beta
82  = (y_dbl - mu_dbl) * inv_beta[n];
83 
84  // log probability
86  logp -= log_beta[n];
88  logp += -y_minus_mu_over_beta - exp(-y_minus_mu_over_beta);
89 
90  // gradients
91  double scaled_diff = inv_beta[n] * exp(-y_minus_mu_over_beta);
93  operands_and_partials.d_x1[n] -= inv_beta[n] - scaled_diff;
95  operands_and_partials.d_x2[n] += inv_beta[n] - scaled_diff;
97  operands_and_partials.d_x3[n]
98  += -inv_beta[n] + y_minus_mu_over_beta * inv_beta[n]
99  - scaled_diff * y_minus_mu_over_beta;
100  }
101  return operands_and_partials.to_var(logp);
102  }
103 
104  template <typename T_y, typename T_loc, typename T_scale>
105  inline
107  gumbel_log(const T_y& y, const T_loc& mu, const T_scale& beta) {
108  return gumbel_log<false>(y,mu,beta);
109  }
110 
111  template <typename T_y, typename T_loc, typename T_scale>
113  gumbel_cdf(const T_y& y, const T_loc& mu, const T_scale& beta) {
114  static const char* function = "stan::prob::gumbel_cdf(%1%)";
115 
120  using stan::math::value_of;
121 
122  double cdf(1.0);
123  // check if any vectors are zero length
124  if (!(stan::length(y)
125  && stan::length(mu)
126  && stan::length(beta)))
127  return cdf;
128 
129  check_not_nan(function, y, "Random variable", &cdf);
130  check_finite(function, mu, "Location parameter", &cdf);
131  check_not_nan(function, beta, "Scale parameter", &cdf);
132  check_positive(function, beta, "Scale parameter", &cdf);
133  check_consistent_sizes(function, y,mu,beta,
134  "Random variable","Location parameter",
135  "Scale parameter", &cdf);
136 
138  operands_and_partials(y, mu, beta);
139 
140  VectorView<const T_y> y_vec(y);
141  VectorView<const T_loc> mu_vec(mu);
142  VectorView<const T_scale> beta_vec(beta);
143  size_t N = max_size(y, mu, beta);
144 
145  for (size_t n = 0; n < N; n++) {
146  const double y_dbl = value_of(y_vec[n]);
147  const double mu_dbl = value_of(mu_vec[n]);
148  const double beta_dbl = value_of(beta_vec[n]);
149  const double scaled_diff = (y_dbl - mu_dbl) / beta_dbl;
150  const double rep_deriv = exp(-scaled_diff - exp(-scaled_diff))
151  / beta_dbl;
152  const double cdf_ = exp(-exp(-scaled_diff));
153  cdf *= cdf_;
154 
156  operands_and_partials.d_x1[n] += rep_deriv / cdf_;
158  operands_and_partials.d_x2[n] -= rep_deriv / cdf_;
160  operands_and_partials.d_x3[n] -= rep_deriv * scaled_diff / cdf_;
161  }
162 
164  for(size_t n = 0; n < stan::length(y); ++n)
165  operands_and_partials.d_x1[n] *= cdf;
166  }
168  for(size_t n = 0; n < stan::length(mu); ++n)
169  operands_and_partials.d_x2[n] *= cdf;
170  }
172  for(size_t n = 0; n < stan::length(beta); ++n)
173  operands_and_partials.d_x3[n] *= cdf;
174  }
175 
176  return operands_and_partials.to_var(cdf);
177  }
178 
179  template <typename T_y, typename T_loc, typename T_scale>
181  gumbel_cdf_log(const T_y& y, const T_loc& mu, const T_scale& beta) {
182  static const char* function = "stan::prob::gumbel_cdf_log(%1%)";
183 
188  using stan::math::value_of;
189 
190  double cdf_log(0.0);
191  // check if any vectors are zero length
192  if (!(stan::length(y)
193  && stan::length(mu)
194  && stan::length(beta)))
195  return cdf_log;
196 
197  check_not_nan(function, y, "Random variable", &cdf_log);
198  check_finite(function, mu, "Location parameter", &cdf_log);
199  check_not_nan(function, beta, "Scale parameter", &cdf_log);
200  check_positive(function, beta, "Scale parameter", &cdf_log);
201  check_consistent_sizes(function, y,mu,beta,
202  "Random variable","Location parameter",
203  "Scale parameter", &cdf_log);
204 
206  operands_and_partials(y, mu, beta);
207 
208  VectorView<const T_y> y_vec(y);
209  VectorView<const T_loc> mu_vec(mu);
210  VectorView<const T_scale> beta_vec(beta);
211  size_t N = max_size(y, mu, beta);
212 
213  for (size_t n = 0; n < N; n++) {
214  const double y_dbl = value_of(y_vec[n]);
215  const double mu_dbl = value_of(mu_vec[n]);
216  const double beta_dbl = value_of(beta_vec[n]);
217  const double scaled_diff = (y_dbl - mu_dbl) / beta_dbl;
218  const double rep_deriv = exp(-scaled_diff) / beta_dbl;
219  cdf_log -= exp(-scaled_diff);
220 
222  operands_and_partials.d_x1[n] += rep_deriv;
224  operands_and_partials.d_x2[n] -= rep_deriv;
226  operands_and_partials.d_x3[n] -= rep_deriv * scaled_diff;
227  }
228 
229  return operands_and_partials.to_var(cdf_log);
230  }
231 
232  template <typename T_y, typename T_loc, typename T_scale>
234  gumbel_ccdf_log(const T_y& y, const T_loc& mu, const T_scale& beta) {
235  static const char* function = "stan::prob::gumbel_ccdf_log(%1%)";
236 
241  using stan::math::value_of;
242 
243  double ccdf_log(0.0);
244  // check if any vectors are zero length
245  if (!(stan::length(y)
246  && stan::length(mu)
247  && stan::length(beta)))
248  return ccdf_log;
249 
250  check_not_nan(function, y, "Random variable", &ccdf_log);
251  check_finite(function, mu, "Location parameter", &ccdf_log);
252  check_not_nan(function, beta, "Scale parameter", &ccdf_log);
253  check_positive(function, beta, "Scale parameter", &ccdf_log);
254  check_consistent_sizes(function, y,mu,beta,
255  "Random variable","Location parameter",
256  "Scale parameter", &ccdf_log);
257 
259  operands_and_partials(y, mu, beta);
260 
261  VectorView<const T_y> y_vec(y);
262  VectorView<const T_loc> mu_vec(mu);
263  VectorView<const T_scale> beta_vec(beta);
264  size_t N = max_size(y, mu, beta);
265 
266  for (size_t n = 0; n < N; n++) {
267  const double y_dbl = value_of(y_vec[n]);
268  const double mu_dbl = value_of(mu_vec[n]);
269  const double beta_dbl = value_of(beta_vec[n]);
270  const double scaled_diff = (y_dbl - mu_dbl) / beta_dbl;
271  const double rep_deriv = exp(-scaled_diff - exp(-scaled_diff))
272  / beta_dbl;
273  const double ccdf_log_ = 1.0 - exp(-exp(-scaled_diff));
274  ccdf_log += log(ccdf_log_);
275 
277  operands_and_partials.d_x1[n] -= rep_deriv / ccdf_log_;
279  operands_and_partials.d_x2[n] += rep_deriv / ccdf_log_;
281  operands_and_partials.d_x3[n] += rep_deriv * scaled_diff / ccdf_log_;
282  }
283 
284  return operands_and_partials.to_var(ccdf_log);
285  }
286 
287  template <class RNG>
288  inline double
289  gumbel_rng(const double mu,
290  const double beta,
291  RNG& rng) {
292  using boost::variate_generator;
293  using boost::uniform_01;
294 
295  static const char* function = "stan::prob::gumbel_rng(%1%)";
296 
299 
300 
301  check_finite(function, mu, "Location parameter", (double*)0);
302  check_positive(function, beta, "Scale parameter", (double*)0);
303 
304  variate_generator<RNG&, uniform_01<> >
305  uniform01_rng(rng, uniform_01<>());
306  return mu - beta * std::log(-std::log(uniform01_rng()));
307  }
308  }
309 }
310 #endif
311 
return_type< T_y, T_loc, T_scale >::type gumbel_log(const T_y &y, const T_loc &mu, const T_scale &beta)
Definition: gumbel.hpp:21
T_return_type to_var(double logp)
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
return_type< T_y, T_loc, T_scale >::type gumbel_ccdf_log(const T_y &y, const T_loc &mu, const T_scale &beta)
Definition: gumbel.hpp:234
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
return_type< T_y, T_loc, T_scale >::type gumbel_cdf(const T_y &y, const T_loc &mu, const T_scale &beta)
Definition: gumbel.hpp:113
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_loc, T_scale >::type gumbel_cdf_log(const T_y &y, const T_loc &mu, const T_scale &beta)
Definition: gumbel.hpp:181
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)
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
double gumbel_rng(const double mu, const double beta, RNG &rng)
Definition: gumbel.hpp:289

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