| 31 | */ |
| 32 | template <class T, class URBG> |
| 33 | std::vector<T> randomSample(std::vector<T> input, size_t num_samples, URBG&& g) { |
| 34 | |
| 35 | std::vector<T> output; |
| 36 | output.reserve(num_samples); |
| 37 | if (4 * num_samples > input.size()) { |
| 38 | // if the sample is a sizeable fraction of the whole population, |
| 39 | // just randomly shuffle the entire population and return the |
| 40 | // first num_samples |
| 41 | std::shuffle(input.begin(), input.end(), g); |
| 42 | for (size_t i = 0; i < num_samples; ++i) { |
| 43 | output.push_back(input[i]); |
| 44 | } |
| 45 | } else { |
| 46 | // if the sample is small, repeatedly sample with replacement until num_samples |
| 47 | // unique values |
| 48 | std::unordered_set<size_t> sample_indices; |
| 49 | std::uniform_int_distribution<> dis(0, input.size()); |
| 50 | while (sample_indices.size() < num_samples) { |
| 51 | sample_indices.insert(dis(std::forward<URBG>(g))); |
| 52 | } |
| 53 | for (auto&& i : sample_indices) { |
| 54 | output.push_back(input[i]); |
| 55 | } |
| 56 | } |
| 57 | return output; |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * Remove one row from matrix. |