Automatic Differentiation
 
Loading...
Searching...
No Matches
categorical_logit_rng.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_PROB_CATEGORICAL_LOGIT_RNG_HPP
2#define STAN_MATH_PRIM_PROB_CATEGORICAL_LOGIT_RNG_HPP
3
10#include <boost/random/uniform_01.hpp>
11#include <boost/random/variate_generator.hpp>
12
13namespace stan {
14namespace math {
15
35template <class RNG>
36inline int categorical_logit_rng(const Eigen::VectorXd& beta, RNG& rng) {
37 using boost::uniform_01;
38 using boost::variate_generator;
39 static constexpr const char* function = "categorical_logit_rng";
40 // Throws in nan and all -inf case
41 check_not_nan(function, "Log odds parameter", beta);
42 check_nonzero_size(function, "Log odds parameter", beta);
43 check_greater(function, "Log odds parameter", beta.maxCoeff(),
45
46 auto is_pos_inf = (beta.array() == INFTY);
47 int num_infty = is_pos_inf.count();
48
49 Eigen::VectorXd theta;
50
51 // softmax is NaN with +inf, so split probability evenly over the
52 // +inf entries and give every other entry zero probability
53 if (num_infty > 0) {
54 theta = is_pos_inf.template cast<double>() / num_infty;
55 } else {
56 theta = softmax(beta);
57 }
58
59 variate_generator<RNG&, uniform_01<> > uniform01_rng(rng, uniform_01<>());
60 Eigen::VectorXd index = cumulative_sum(theta);
61
62 // index may sum to just below 1, so stop at the last nonzero entry
63 int last = theta.size() - 1;
64 while (theta(last) == 0) {
65 last--;
66 }
67 double c = uniform01_rng();
68 int b = 0;
69 while (b < last && c >= index(b)) {
70 b++;
71 }
72 return b + 1;
73}
74} // namespace math
75} // namespace stan
76#endif
int categorical_logit_rng(const Eigen::VectorXd &beta, RNG &rng)
Return a draw from a Categorical distribution given a vector of unnormalized log probabilities and a ...
static constexpr double NEGATIVE_INFTY
Negative infinity.
Definition constants.hpp:49
auto softmax(T &&x)
Return the softmax of each vector in a container of fvar values.
Definition softmax.hpp:23
auto cumulative_sum(T_vec &&v)
Return the cumulative sum of the specified vector.
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
void check_nonzero_size(const char *function, const char *name, const T_y &y)
Check if the specified matrix/vector is of non-zero size.
fvar< T > beta(const fvar< T > &x1, const fvar< T > &x2)
Return fvar with the beta function applied to the specified arguments and its gradient.
Definition beta.hpp:51
void check_greater(const char *function, const char *name, const T_y &y, const T_low &low, Idxs... idxs)
Throw an exception if y is not strictly greater than low.
static constexpr double INFTY
Positive infinity.
Definition constants.hpp:44
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...