1 #ifndef STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__MULTINOMIAL_HPP
2 #define STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__MULTINOMIAL_HPP
4 #include <boost/math/special_functions/gamma.hpp>
5 #include <boost/random/uniform_01.hpp>
6 #include <boost/random/variate_generator.hpp>
22 template <
bool propto,
24 typename boost::math::tools::promote_args<T_prob>::type
26 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
27 static const char*
function =
"stan::prob::multinomial_log(%1%)";
32 using boost::math::tools::promote_args;
35 typename promote_args<T_prob>::type lp(0.0);
40 ns.size(),
"Size of number of trials variable",
41 theta.rows(),
"rows of probabilities parameter",
47 for (
unsigned int i = 0; i < ns.size(); ++i)
50 for (
unsigned int i = 0; i < ns.size(); ++i)
54 for (
unsigned int i = 0; i < ns.size(); ++i)
59 template <
typename T_prob>
60 typename boost::math::tools::promote_args<T_prob>::type
62 const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
63 return multinomial_log<false>(ns,theta);
67 inline std::vector<int>
71 static const char*
function =
"stan::prob::multinomial_rng(%1%)";
75 check_simplex(
function, theta,
"Probabilites parameter", (
double*)0);
76 check_positive(
function,N,
"number of trials variables", (
double*)0);
78 std::vector<int> result(theta.size(),0);
79 double mass_left = 1.0;
81 for (
int k = 0; n_left > 0 && k < theta.size(); ++k) {
82 double p = theta[k] / mass_left;
86 mass_left -= theta[k];
bool check_size_match(const char *function, T_size1 i, const char *name_i, T_size2 j, const char *name_j, T_result *result)
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...
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.
std::vector< int > multinomial_rng(const Eigen::Matrix< double, Eigen::Dynamic, 1 > &theta, const int N, RNG &rng)
fvar< T > sum(const Eigen::Matrix< fvar< T >, R, C > &m)
fvar< T > lgamma(const fvar< T > &x)
int binomial_rng(const int N, const double theta, RNG &rng)
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
bool check_nonnegative(const char *function, const T_y &y, const char *name, T_result *result)
bool check_positive(const char *function, const T_y &y, const char *name, T_result *result)
fvar< T > multiply_log(const fvar< T > &x1, const fvar< T > &x2)
boost::math::tools::promote_args< T_prob >::type multinomial_log(const std::vector< int > &ns, const Eigen::Matrix< T_prob, Eigen::Dynamic, 1 > &theta)