32 #ifndef MCKL_RANDOM_DISCRETE_DISTRIBUTION_HPP 33 #define MCKL_RANDOM_DISCRETE_DISTRIBUTION_HPP 42 template <
typename IntType>
58 template <
typename InputIter>
59 param_type(InputIter first, InputIter last) : probability_(first, last)
65 : probability_(weights.begin(), weights.end())
70 template <
typename UnaryOperation>
72 UnaryOperation unary_op)
74 probability_.reserve(count);
75 double delta = (xmax - xmin) / static_cast<double>(count);
77 for (std::size_t i = 0; i != count; ++i) {
78 probability_.push_back(
79 unary_op(xmin + static_cast<double>(i) * delta));
89 return param1.probability_ == param2.probability_;
95 return !(param1 == param2);
98 template <
typename CharT,
typename Traits>
100 std::basic_ostream<CharT, Traits> &os,
const param_type ¶m)
106 os << param.probability_;
111 template <
typename CharT,
typename Traits>
113 std::basic_istream<CharT, Traits> &is,
param_type ¶m)
124 if (is_positive(probability, sum)) {
125 mul(probability.size(), 1 / sum, probability.data(),
127 param.probability_ = std::move(probability);
129 is.setstate(std::ios_base::failbit);
143 if (probability_.size() == 0) {
148 bool flag = is_positive(probability_, sum);
150 "**DiscreteDistribution** constructed with negative weights");
152 mul(probability_.size(), 1 / sum, probability_.data(),
153 probability_.data());
160 for (std::size_t i = 0; i != probability.size(); ++i) {
161 sum += probability[i];
162 if (probability[i] < 0) {
167 return flag && sum > 0;
173 template <
typename InputIter>
183 template <
typename UnaryOperation>
185 std::size_t count,
double xmin,
double xmax, UnaryOperation &&unary_op)
186 :
param_type(count, xmin, xmax,
std::forward<UnaryOperation>(unary_op))
193 : param_(
std::move(param))
201 return param_.size() == 0 ? 0 : param_.size() - 1;
208 template <
typename RNGType>
212 rng, param_.probability_.begin(), param_.probability_.end(),
true);
233 template <
typename RNGType,
typename InputIter>
235 bool normalized =
false)
const 238 typename std::iterator_traits<InputIter>::value_type;
241 value_type u =
u01(rng);
245 1 / std::accumulate(first, last, const_zero<value_type>());
248 while (first != last) {
249 accw += *first * mulw;
262 while (first != last) {
277 return dist1.param_ == dist2.param_;
283 return !(dist1 == dist2);
286 template <
typename CharT,
typename Traits>
295 template <
typename CharT,
typename Traits>
299 is >> std::ws >> dist.param_;
313 #endif // MCKL_RANDOM_DISCRETE_DISTRIBUTION_HPP DiscreteDistribution(std::size_t count, double xmin, double xmax, UnaryOperation &&unary_op)
void mul(std::size_t n, const float *a, const float *b, float *y)
friend bool operator==(const distribution_type &dist1, const distribution_type &dist2)
param_type(InputIter first, InputIter last)
DiscreteDistribution(const param_type ¶m)
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
DiscreteDistribution(param_type &¶m)
RealType u01(UIntType u)
Convert uniform unsigned integers to floating points within [0, 1].
DiscreteDistribution(std::initializer_list< double > weights)
result_type operator()(RNGType &rng) const
friend bool operator!=(const distribution_type &dist1, const distribution_type &dist2)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, distribution_type &dist)
friend bool operator==(const param_type ¶m1, const param_type ¶m2)
param_type(std::size_t count, double xmin, double xmax, UnaryOperation unary_op)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const param_type ¶m)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const distribution_type &dist)
Standard uniform distribution on [0, 1)
DiscreteDistribution(InputIter first, InputIter last)
Draw a single sample given weights.
Vector< double > probability() const
DiscreteDistribution()=default
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, param_type ¶m)
param_type(std::initializer_list< double > weights)
Vector< double > probability() const
result_type operator()(RNGType &rng, InputIter first, InputIter last, bool normalized=false) const
Draw sample with external probabilities.
DiscreteDistribution< IntType > distribution_type
friend bool operator!=(const param_type ¶m1, const param_type ¶m2)
#define MCKL_DEFINE_RANDOM_DISTRIBUTION_ASSERT_INT_TYPE(Name, MinBits)
void runtime_assert(bool cond, const char *msg, bool soft=false)