12 #ifndef EIGENRAND_MVDISTS_MULTINOMIAL_H
13 #define EIGENRAND_MVDISTS_MULTINOMIAL_H
25 template<
typename _Scalar = int32_t, Index Dim = -1>
28 static_assert(std::is_same<_Scalar, int32_t>::value,
"`MultinomialGen` needs integral types.");
30 Matrix<double, Dim, 1> probs;
40 template<
typename WeightTy>
42 : trials{ _trials }, probs{ _weights.template cast<double>() }, discrete(probs.data(), probs.data() + probs.size())
44 eigen_assert(_weights.cols() == 1);
45 for (Index i = 0; i < probs.size(); ++i)
47 eigen_assert(probs[i] >= 0);
55 Index dims()
const {
return probs.rows(); }
57 template<
typename Urng>
58 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
60 const Index dim = probs.size();
61 Matrix<_Scalar, Dim, -1> ret(dim, samples);
64 for (Index j = 0; j < samples; ++j)
66 ret.col(j) = generate(urng);
90 template<
typename Urng>
91 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
93 const Index dim = probs.size();
94 Matrix<_Scalar, Dim, 1> ret(dim);
98 auto d =
discrete.template generate<Matrix<_Scalar, -1, 1>>(trials, 1, urng).eval();
99 for (Index i = 0; i < trials; ++i)
131 template<
typename IntTy,
typename WeightTy>
144 template<
typename _Scalar, Index Dim = -1>
147 Matrix<_Scalar, Dim, 1> alpha;
148 std::vector<GammaGen<_Scalar>> gammas;
156 template<
typename AlphaTy>
160 eigen_assert(_alpha.cols() == 1);
161 for (Index i = 0; i < alpha.size(); ++i)
163 eigen_assert(alpha[i] > 0);
164 gammas.emplace_back(alpha[i]);
171 Index dims()
const {
return alpha.rows(); }
173 template<
typename Urng>
174 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
176 const Index dim = alpha.size();
177 Matrix<_Scalar, Dim, -1> ret(dim, samples);
178 Matrix<_Scalar, -1, 1> tmp(samples);
179 for (Index i = 0; i < dim; ++i)
181 tmp = gammas[i].generateLike(tmp, urng);
182 ret.row(i) = tmp.transpose();
184 ret.array().rowwise() /= ret.array().colwise().sum();
188 template<
typename Urng>
189 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
191 const Index dim = alpha.size();
192 Matrix<_Scalar, Dim, 1> ret(dim);
193 for (Index i = 0; i < dim; ++i)
195 ret[i] = gammas[i].template generate<Matrix<_Scalar, 1, 1>>(1, 1, urng)(0);
210 template<
typename AlphaTy>