1 #ifndef STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP
2 #define STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__CATEGORICAL_HPP
4 #include <boost/random/uniform_01.hpp>
5 #include <boost/random/variate_generator.hpp>
20 template <
bool propto,
22 typename boost::math::tools::promote_args<T_prob>::type
24 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
25 static const char*
function =
"stan::prob::categorical_log(%1%)";
29 using boost::math::tools::promote_args;
36 "Number of categories",
41 "Probabilities parameter",
46 "Probabilities parameter",
52 return log(theta(n-1));
56 template <
typename T_prob>
58 typename boost::math::tools::promote_args<T_prob>::type
61 Eigen::Dynamic,1> >::type n,
62 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
64 return categorical_log<false>(n,theta);
69 template <
bool propto,
71 typename boost::math::tools::promote_args<T_prob>::type
73 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
74 static const char*
function =
"stan::prob::categorical_log(%1%)";
76 using boost::math::tools::promote_args;
85 for (
size_t i = 0; i < ns.size(); ++i)
87 "element of outcome array",
92 "Probabilities parameter",
97 "Probabilities parameter",
108 Eigen::Matrix<T_prob,Eigen::Dynamic,1> log_theta(theta.size());
109 for (
int i = 0; i < theta.size(); ++i)
110 log_theta(i) =
log(theta(i));
112 Eigen::Matrix<typename boost::math::tools::promote_args<T_prob>::type,
113 Eigen::Dynamic,1> log_theta_ns(ns.size());
114 for (
size_t i = 0; i < ns.size(); ++i)
115 log_theta_ns(i) = log_theta(ns[i] - 1);
117 return sum(log_theta_ns);
121 template <
typename T_prob>
123 typename boost::math::tools::promote_args<T_prob>::type
125 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
126 return categorical_log<false>(ns,theta);
133 using boost::variate_generator;
134 using boost::uniform_01;
137 static const char*
function =
"stan::prob::categorical_rng(%1%)";
140 "Probabilities parameter", (
double*)0);
142 variate_generator<RNG&, uniform_01<> >
143 uniform01_rng(rng, uniform_01<>());
145 Eigen::VectorXd index(theta.rows());
148 for(
int i = 0; i < theta.rows(); i++) {
149 for(
int j = i; j < theta.rows(); j++)
150 index(j) += theta(i,0);
153 double c = uniform01_rng();
155 while(c > index(b,0))
bool check_bounded(const char *function, const T_y &y, const T_low &low, const T_high &high, const char *name, T_result *result)
boost::math::tools::promote_args< T_prob >::type categorical_log(int n, const Eigen::Matrix< T_prob, Eigen::Dynamic, 1 > &theta)
bool check_simplex(const char *function, const Eigen::Matrix< T_prob, Eigen::Dynamic, 1 > &theta, const char *name, T_result *result)
Return true if the specified vector is simplex.
int categorical_rng(const Eigen::Matrix< double, Eigen::Dynamic, 1 > &theta, RNG &rng)
fvar< T > sum(const Eigen::Matrix< fvar< T >, R, C > &m)
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Primary template class for the metaprogram to compute the index type of a container.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
double sum(std::vector< double > &x)
fvar< T > log(const fvar< T > &x)