23 if (selected.size() != weights.size() || quota < 0 || quota > weights.size())
24 throw std::invalid_argument(
"Weighted selection: invalid mask or quota.");
27 for (Index i = 0; i < weights.size(); ++i)
29 if (!std::isfinite(weights(i)) || weights(i) < 0.0f)
30 throw std::invalid_argument(
"Weighted selection: weights must be finite and nonnegative.");
31 if (!selected(i) && weights(i) > 0.0f) ++available;
34 const Index needed = quota - selected.count();
35 if (needed <= 0)
return;
36 if (needed > available)
37 throw std::invalid_argument(
"Weighted selection: insufficient positive weights.");
39 std::vector<std::pair<double, Index>> priorities;
40 priorities.reserve(
size_t(available));
41 for (Index i = 0; i < weights.size(); ++i)
43 if (selected(i) || weights(i) == 0.0f)
continue;
44 const double draw = double(uniform());
45 if (!std::isfinite(draw) || draw < 0.0 || draw > 1.0)
46 throw std::invalid_argument(
"Weighted selection: uniform draw must be in [0,1].");
47 const double interior = std::min(draw, std::nextafter(1.0, 0.0));
48 priorities.emplace_back(-std::log1p(-interior) /
double(weights(i)), i);
52 std::partial_sort(priorities.begin(), priorities.begin() + needed, priorities.end());
53 for (Index rank = 0; rank < needed; ++rank)
54 selected(priorities[
size_t(rank)].second) =
true;
void fill_weighted_selection(const VectorR &weights, Index quota, VectorB &selected, Uniform &&uniform)
Definition weighted_selection.h:21
Eigen::Matrix< float, Eigen::Dynamic, 1 > VectorR
Definition opennn_types.h:335
Eigen::Matrix< bool, Eigen::Dynamic, 1 > VectorB
Definition opennn_types.h:337