rippled
Loading...
Searching...
No Matches
src/test/csf/random.h
1#ifndef XRPL_TEST_CSF_RANDOM_H_INCLUDED
2#define XRPL_TEST_CSF_RANDOM_H_INCLUDED
3
4#include <random>
5#include <vector>
6
7namespace ripple {
8namespace test {
9namespace csf {
10
20template <class T, class G>
23{
24 using std::swap;
25
26 for (int i = 0; i < v.size() - 1; ++i)
27 {
28 // pick a random item weighted by w
29 std::discrete_distribution<> dd(w.begin() + i, w.end());
30 auto idx = dd(g);
31 std::swap(v[i], v[idx]);
32 std::swap(w[i], w[idx]);
33 }
34 return v;
35}
36
45template <class RandomNumberDistribution, class Generator>
47sample(std::size_t size, RandomNumberDistribution dist, Generator& g)
48{
50 std::generate(res.begin(), res.end(), [&dist, &g]() { return dist(g); });
51 return res;
52}
53
61template <class RAIter, class Generator>
63{
64 RAIter first_, last_;
66 Generator g_;
67
68public:
76 RAIter first,
77 RAIter last,
78 std::vector<double> const& w,
79 Generator& g)
80 : first_{first}, last_{last}, dd_{w.begin(), w.end()}, g_{g}
81 {
83 static_assert(
85 "Selector only supports random access iterators.");
86 // TODO: Allow for forward iterators
87 }
88
91 {
92 auto idx = dd_(g_);
93 return *(first_ + idx);
94 }
95};
96
97template <typename Iter, typename Generator>
98Selector<Iter, Generator>
99makeSelector(Iter first, Iter last, std::vector<double> const& w, Generator& g)
100{
101 return Selector<Iter, Generator>(first, last, w, g);
102}
103
104//------------------------------------------------------------------------------
105// Additional distributions of interest not defined in <random>
106
110{
111 double t_;
112
113public:
114 ConstantDistribution(double const& t) : t_{t}
115 {
116 }
117
118 template <class Generator>
119 inline double
120 operator()(Generator&)
121 {
122 return t_;
123 }
124};
125
133{
134 double xmin_;
135 double a_;
136 double inv_;
138
139public:
140 using result_type = double;
141
142 PowerLawDistribution(double xmin, double a) : xmin_{xmin}, a_{a}
143 {
144 inv_ = 1.0 / (1.0 - a_);
145 }
146
147 template <class Generator>
148 inline double
149 operator()(Generator& g)
150 {
151 // use inverse transform of CDF to sample
152 // CDF is P(X <= x): 1 - (x/xmin)^(1-a)
153 return xmin_ * std::pow(1 - uf_(g), inv_);
154 }
155};
156
157} // namespace csf
158} // namespace test
159} // namespace ripple
160
161#endif
T begin(T... args)
Constant "distribution" that always returns the same value.
Power-law distribution with PDF.
std::uniform_real_distribution< double > uf_
Invocable that returns random samples from a range according to a discrete distribution.
Selector(RAIter first, RAIter last, std::vector< double > const &w, Generator &g)
Constructor.
std::iterator_traits< RAIter >::value_type operator()()
std::discrete_distribution dd_
T end(T... args)
T generate(T... args)
Selector< Iter, Generator > makeSelector(Iter first, Iter last, std::vector< double > const &w, Generator &g)
std::vector< T > random_weighted_shuffle(std::vector< T > v, std::vector< double > w, G &g)
Return a randomly shuffled copy of vector based on weights w.
std::vector< typename RandomNumberDistribution::result_type > sample(std::size_t size, RandomNumberDistribution dist, Generator &g)
Generate a vector of random samples.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
T pow(T... args)
T size(T... args)
T swap(T... args)