xrpld
Loading...
Searching...
No Matches
src/test/csf/random.h
1#pragma once
2
3#include <random>
4#include <vector>
5
6namespace xrpl::test::csf {
7
17template <class T, class G>
18std::vector<T>
20{
21 using std::swap;
22
23 for (int i = 0; i < v.size() - 1; ++i)
24 {
25 // pick a random item weighted by w
26 std::discrete_distribution<> dd(w.begin() + i, w.end()); // NOLINT(misc-const-correctness)
27 auto idx = dd(g);
28 std::swap(v[i], v[idx]);
29 std::swap(w[i], w[idx]);
30 }
31 return v;
32}
33
42template <class RandomNumberDistribution, class Generator>
44sample(std::size_t size, RandomNumberDistribution dist, Generator& g)
45{
47 std::ranges::generate(res, [&dist, &g]() { return dist(g); });
48 return res;
49}
50
58template <class RAIter, class Generator>
60{
61 RAIter first_, last_;
64
65public:
72 Selector(RAIter first, RAIter last, std::vector<double> const& w, Generator& g)
73 : first_{first}, last_{last}, dd_{w.begin(), w.end()}, g_{g}
74 {
76 static_assert(
78 "Selector only supports random access iterators.");
79 // TODO: Allow for forward iterators
80 }
81
84 {
85 auto idx = dd_(g_);
86 return *(first_ + idx);
87 }
88};
89
90template <typename Iter, typename Generator>
91Selector<Iter, Generator>
92makeSelector(Iter first, Iter last, std::vector<double> const& w, Generator& g)
93{
94 return Selector<Iter, Generator>(first, last, w, g);
95}
96
97//------------------------------------------------------------------------------
98// Additional distributions of interest not defined in <random>
99
103{
104 double t_;
105
106public:
107 ConstantDistribution(double const& t) : t_{t}
108 {
109 }
110
111 template <class Generator>
112 double
114 {
115 return t_;
116 }
117};
118
126{
127 double xmin_;
128 double a_;
129 double inv_;
131
132public:
133 using result_type = double;
134
135 PowerLawDistribution(double xmin, double a) : xmin_{xmin}, a_{a}
136 {
137 inv_ = 1.0 / (1.0 - a_);
138 }
139
140 template <class Generator>
141 double
143 {
144 // use inverse transform of CDF to sample
145 // CDF is P(X <= x): 1 - (x/xmin)^(1-a)
146 return xmin_ * std::pow(1 - uf_(g), inv_);
147 }
148};
149
150} // namespace xrpl::test::csf
T begin(T... args)
std::uniform_real_distribution< double > uf_
Invocable that returns random samples from a range according to a discrete distribution.
std::discrete_distribution dd_
std::iterator_traits< RAIter >::value_type operator()()
Selector(RAIter first, RAIter last, std::vector< double > const &w, Generator &g)
Constructor.
T end(T... args)
T generate(T... args)
T is_same_v
Selector< Iter, Generator > makeSelector(Iter first, Iter last, std::vector< double > const &w, Generator &g)
std::vector< typename RandomNumberDistribution::result_type > sample(std::size_t size, RandomNumberDistribution dist, Generator &g)
Generate a vector of random samples.
std::vector< T > randomWeightedShuffle(std::vector< T > v, std::vector< double > w, G &g)
Return a randomly shuffled copy of vector based on weights w.
T pow(T... args)
T size(T... args)
T swap(T... args)