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);
58 Index dims()
const {
return probs.rows(); }
60 template<
typename Urng>
61 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
63 const Index dim = probs.size();
64 Matrix<_Scalar, Dim, -1> ret(dim, samples);
67 for (Index j = 0; j < samples; ++j)
69 ret.col(j) = generate(urng);
93 template<
typename Urng>
94 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
96 const Index dim = probs.size();
97 Matrix<_Scalar, Dim, 1> ret(dim);
101 auto d =
discrete.template generate<Matrix<_Scalar, -1, 1>>(trials, 1, urng).eval();
102 for (Index i = 0; i < trials; ++i)
134 template<
typename IntTy,
typename WeightTy>
147 template<
typename _Scalar, Index Dim = -1>
150 Matrix<_Scalar, Dim, 1> alpha;
151 std::vector<GammaGen<_Scalar>> gammas;
159 template<
typename AlphaTy>
163 eigen_assert(_alpha.cols() == 1);
164 for (Index i = 0; i < alpha.size(); ++i)
166 eigen_assert(alpha[i] > 0);
167 gammas.emplace_back(alpha[i]);
174 Index dims()
const {
return alpha.rows(); }
176 template<
typename Urng>
177 inline Matrix<_Scalar, Dim, -1> generate(Urng&& urng, Index samples)
179 const Index dim = alpha.size();
180 Matrix<_Scalar, Dim, -1> ret(dim, samples);
181 Matrix<_Scalar, -1, 1> tmp(samples);
182 for (Index i = 0; i < dim; ++i)
184 tmp = gammas[i].generateLike(tmp, urng);
185 ret.row(i) = tmp.transpose();
187 ret.array().rowwise() /= ret.array().colwise().sum();
191 template<
typename Urng>
192 inline Matrix<_Scalar, Dim, 1> generate(Urng&& urng)
194 const Index dim = alpha.size();
195 Matrix<_Scalar, Dim, 1> ret(dim);
196 for (Index i = 0; i < dim; ++i)
198 ret[i] = gammas[i].template generate<Matrix<_Scalar, 1, 1>>(1, 1, urng)(0);
213 template<
typename AlphaTy>
Generator of reals on a Dirichlet distribution.
Definition: Multinomial.h:149
DirichletGen(const MatrixBase< AlphaTy > &_alpha)
Construct a new Dirichlet generator.
Definition: Multinomial.h:160
Generator of integers on the interval [0, n), where the probability of each individual integer i is p...
Definition: Discrete.h:327
Generator of real vectors on a multinomial distribution.
Definition: Multinomial.h:27
MultinomialGen(_Scalar _trials, const MatrixBase< WeightTy > &_weights)
Construct a new multinomial generator.
Definition: Multinomial.h:41
Base class of all multivariate random vector generators.
Definition: Basic.h:84
auto makeMultinomialGen(IntTy trials, const MatrixBase< WeightTy > &probs) -> MultinomialGen< IntTy, MatrixBase< WeightTy >::RowsAtCompileTime >
helper function constructing Eigen::Rand::MultinomialGen
Definition: Multinomial.h:135
auto makeDirichletGen(const MatrixBase< AlphaTy > &alpha) -> DirichletGen< typename MatrixBase< AlphaTy >::Scalar, MatrixBase< AlphaTy >::RowsAtCompileTime >
helper function constructing Eigen::Rand::DirichletGen
Definition: Multinomial.h:214
const DiscreteType< Derived, Urng > discrete(Index rows, Index cols, Urng &&urng, RealIter first, RealIter last)
generates random integers on the interval [0, n), where the probability of each individual integer i ...
Definition: Discrete.h:1292