32 #ifndef VSMC_RNG_DISCRETE_DISTRIBUTION_HPP 33 #define VSMC_RNG_DISCRETE_DISTRIBUTION_HPP 38 #define VSMC_RUNTIME_ASSERT_RNG_DISCRETE_DISTRIBUTION_POSITIVE(flag) \ 39 VSMC_RUNTIME_ASSERT( \ 40 (flag), "**DiscreteDistribution** WEIGHTS ARE NOT NON-NEGATIVE") 47 template <
typename IntType>
62 template <
typename InputIter>
63 param_type(InputIter first, InputIter last) : probability_(first, last)
69 : probability_(weights.begin(), weights.end())
74 template <
typename UnaryOperation>
76 UnaryOperation unary_op)
78 probability_.reserve(count);
79 double delta = (xmax - xmin) / static_cast<double>(count);
81 for (std::size_t i = 0; i != count; ++i)
82 probability_.push_back(
83 unary_op(xmin + static_cast<double>(i) * delta));
92 if (param1.probability_.size() != param2.probability_.size())
95 for (std::size_t i = 0; i != param1.probability_.size(); ++i)
97 param1.probability_[i], param2.probability_[i]))
106 return !(param1 == param2);
109 template <
typename CharT,
typename Traits>
111 std::basic_ostream<CharT, Traits> &os,
const param_type ¶m)
116 os << param.probability_.size() <<
' ';
117 for (std::size_t i = 0; i != param.probability_.size(); ++i)
118 os << param.probability_[i] <<
' ';
123 template <
typename CharT,
typename Traits>
125 std::basic_istream<CharT, Traits> &is,
param_type ¶m)
136 for (std::size_t i = 0; i != n; ++i)
137 is >> std::ws >> probability[i];
141 if (is_positive(probability, sum)) {
142 mul(probability.size(), 1 / sum, probability.data(),
144 param.probability_ = std::move(probability);
146 is.setstate(std::ios_base::failbit);
160 if (probability_.size() == 0)
165 bool flag = is_positive(probability_, sum);
168 is_positive(probability_, sum);
170 mul(probability_.size(), 1 / sum, probability_.data(),
171 probability_.data());
180 for (std::size_t i = 0; i != probability.size(); ++i) {
181 sum += probability[i];
182 if (probability[i] < 0)
186 return flag && sum > 0;
192 template <
typename InputIter>
202 template <
typename UnaryOperation>
204 std::size_t count,
double xmin,
double xmax, UnaryOperation &&unary_op)
205 :
param_type(count, xmin, xmax,
std::forward<UnaryOperation>(unary_op))
212 : param_(
std::move(param))
220 return param_.size() == 0 ? 0 : param_.size() - 1;
225 template <
typename RNGType>
229 rng, param_.probability_.begin(), param_.probability_.end(),
true);
250 template <
typename RNGType,
typename InputIter>
252 bool normalized =
false)
const 255 typename std::iterator_traits<InputIter>::value_type;
258 value_type u = u01(rng);
262 1 / std::accumulate(first, last, static_cast<value_type>(0));
265 while (first != last) {
266 accw += *first * mulw;
278 while (first != last) {
292 return dist1.param_ == dist2.param_;
298 return !(dist1 == dist2);
301 template <
typename CharT,
typename Traits>
310 template <
typename CharT,
typename Traits>
314 is >> std::ws >> dist.param_;
327 #endif // VSMC_RNG_DISCRETE_DISTRIBUTION_HPP
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
void mul(std::size_t n, const float *a, const float *b, float *y)
param_type(InputIter first, InputIter last)
friend bool operator==(const distribution_type &dist1, const distribution_type &dist2)
DiscreteDistribution(InputIter first, InputIter last)
bool is_equal(const T &a, const T &b)
param_type(std::size_t count, double xmin, double xmax, UnaryOperation unary_op)
result_type operator()(RNGType &rng) const
param_type(std::initializer_list< double > weights)
DiscreteDistribution(param_type &¶m)
friend bool operator!=(const distribution_type &dist1, const distribution_type &dist2)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const param_type ¶m)
DiscreteDistribution(std::initializer_list< double > weights)
result_type operator()(RNGType &rng, InputIter first, InputIter last, bool normalized=false) const
Draw sample with external probabilities.
DiscreteDistribution< IntType > distribution_type
Vector< double > probability() const
DiscreteDistribution(const param_type ¶m)
#define VSMC_RUNTIME_ASSERT_RNG_DISCRETE_DISTRIBUTION_POSITIVE(flag)
DiscreteDistribution(std::size_t count, double xmin, double xmax, UnaryOperation &&unary_op)
friend bool operator==(const param_type ¶m1, const param_type ¶m2)
Vector< double > probability() const
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, distribution_type &dist)
Standard uniform distribution.
Draw a single sample given weights.
friend bool operator!=(const param_type ¶m1, const param_type ¶m2)
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const distribution_type &dist)
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, param_type ¶m)