Stan  1.3
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
multinomial.hpp
Go to the documentation of this file.
1 #ifndef __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__MULTINOMIAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__MULTIVARIATE__DISCRETE__MULTINOMIAL_HPP__
3 
4 #include <boost/math/special_functions/gamma.hpp>
5 #include <boost/random/uniform_01.hpp>
6 #include <boost/random/variate_generator.hpp>
7 
12 #include <stan/prob/constants.hpp>
15 #include <stan/prob/traits.hpp>
16 
17 namespace stan {
18 
19  namespace prob {
20  // Multinomial(ns|N,theta) [0 <= n <= N; SUM ns = N;
21  // 0 <= theta[n] <= 1; SUM theta = 1]
22  template <bool propto,
23  typename T_prob,
24  class Policy>
25  typename boost::math::tools::promote_args<T_prob>::type
26  multinomial_log(const std::vector<int>& ns,
27  const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
28  const Policy&) {
29  static const char* function = "stan::prob::multinomial_log(%1%)";
30 
34  using boost::math::tools::promote_args;
35  using boost::math::lgamma;
36 
37  typename promote_args<T_prob>::type lp(0.0);
38  if (!check_nonnegative(function, ns, "Number of trials variable", &lp, Policy()))
39  return lp;
40  if (!check_simplex(function, theta, "Probabilites parameter",
41  &lp, Policy()))
42  return lp;
43  if (!check_size_match(function,
44  ns.size(), "Size of number of trials variable",
45  theta.rows(), "rows of probabilities parameter",
46  &lp, Policy()))
47  return lp;
49 
51  double sum = 1.0;
52  for (unsigned int i = 0; i < ns.size(); ++i)
53  sum += ns[i];
54  lp += lgamma(sum);
55  for (unsigned int i = 0; i < ns.size(); ++i)
56  lp -= lgamma(ns[i] + 1.0);
57  }
59  for (unsigned int i = 0; i < ns.size(); ++i)
60  lp += multiply_log(ns[i], theta[i]);
61  return lp;
62  }
63 
64 
65  template <bool propto,
66  typename T_prob>
67  typename boost::math::tools::promote_args<T_prob>::type
68  multinomial_log(const std::vector<int>& ns,
69  const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
70  return multinomial_log<propto>(ns,theta,stan::math::default_policy());
71  }
72 
73  template <typename T_prob,
74  class Policy>
75  typename boost::math::tools::promote_args<T_prob>::type
76  multinomial_log(const std::vector<int>& ns,
77  const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta,
78  const Policy&) {
79  return multinomial_log<false>(ns,theta,Policy());
80  }
81 
82  template <typename T_prob>
83  typename boost::math::tools::promote_args<T_prob>::type
84  multinomial_log(const std::vector<int>& ns,
85  const Eigen::Matrix<T_prob,Eigen::Dynamic,1>& theta) {
86  return multinomial_log<false>(ns,theta,stan::math::default_policy());
87  }
88 
89  template <class RNG>
90  inline std::vector<int>
91  multinomial_rng(const Eigen::Matrix<double,Eigen::Dynamic,1>& theta,
92  const int N,
93  RNG& rng) {
94  std::vector<int> result(N,0);
95  double mass_left = 1.0;
96  int n_left = N;
97  for (int k = 0; n_left > 0 && k < theta.size(); ++k) {
98  result[k] = binomial_rng(n_left,theta[k] / mass_left,rng);
99  n_left -= result[k];
100  mass_left -= theta[k];
101  }
102  // for (int n = 0; n < N; ++n)
103  // ++result[categorical_rng(theta,rng) - 1];
104  return result;
105  }
106 
107 
108  }
109 }
110 #endif

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