rippled
Loading...
Searching...
No Matches
src/test/csf/random.h
1#pragma once
2
3#include <random>
4#include <vector>
5
6namespace xrpl {
7namespace test {
8namespace csf {
9
19template <class T, class G>
22{
23 using std::swap;
24
25 for (int i = 0; i < v.size() - 1; ++i)
26 {
27 // pick a random item weighted by w
28 std::discrete_distribution<> dd(w.begin() + i, w.end());
29 auto idx = dd(g);
30 std::swap(v[i], v[idx]);
31 std::swap(w[i], w[idx]);
32 }
33 return v;
34}
35
44template <class RandomNumberDistribution, class Generator>
46sample(std::size_t size, RandomNumberDistribution dist, Generator& g)
47{
49 std::generate(res.begin(), res.end(), [&dist, &g]() { return dist(g); });
50 return res;
51}
52
60template <class RAIter, class Generator>
62{
63 RAIter first_, last_;
65 Generator g_;
66
67public:
74 Selector(RAIter first, RAIter last, std::vector<double> const& w, Generator& g)
75 : first_{first}, last_{last}, dd_{w.begin(), w.end()}, g_{g}
76 {
78 static_assert(
80 "Selector only supports random access iterators.");
81 // TODO: Allow for forward iterators
82 }
83
86 {
87 auto idx = dd_(g_);
88 return *(first_ + idx);
89 }
90};
91
92template <typename Iter, typename Generator>
93Selector<Iter, Generator>
94makeSelector(Iter first, Iter last, std::vector<double> const& w, Generator& g)
95{
96 return Selector<Iter, Generator>(first, last, w, g);
97}
98
99//------------------------------------------------------------------------------
100// Additional distributions of interest not defined in <random>
101
105{
106 double t_;
107
108public:
109 ConstantDistribution(double const& t) : t_{t}
110 {
111 }
112
113 template <class Generator>
114 inline double
115 operator()(Generator&)
116 {
117 return t_;
118 }
119};
120
128{
129 double xmin_;
130 double a_;
131 double inv_;
133
134public:
135 using result_type = double;
136
137 PowerLawDistribution(double xmin, double a) : xmin_{xmin}, a_{a}
138 {
139 inv_ = 1.0 / (1.0 - a_);
140 }
141
142 template <class Generator>
143 inline double
144 operator()(Generator& g)
145 {
146 // use inverse transform of CDF to sample
147 // CDF is P(X <= x): 1 - (x/xmin)^(1-a)
148 return xmin_ * std::pow(1 - uf_(g), inv_);
149 }
150};
151
152} // namespace csf
153} // namespace test
154} // namespace xrpl
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.
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)
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 > random_weighted_shuffle(std::vector< T > v, std::vector< double > w, G &g)
Return a randomly shuffled copy of vector based on weights w.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
T pow(T... args)
T size(T... args)
T swap(T... args)