xrpld
Loading...
Searching...
No Matches
src/tests/libxrpl/csf/random.h
1#pragma once
2
3#include <algorithm>
4#include <cstddef>
5#include <iterator>
6#include <random>
7#include <vector>
8
9namespace xrpl::test::csf {
10
21template <class T, class G>
22std::vector<T>
24{
25 using std::swap;
26
27 for (auto i = 0uz; i + 1 < v.size(); ++i)
28 {
29 // Pick a random item from the unplaced tail, weighted by w.
30 // NOLINTNEXTLINE(misc-const-correctness)
32 auto const idx = i + dd(g);
33 std::swap(v[i], v[idx]);
34 std::swap(w[i], w[idx]);
35 }
36 return v;
37}
38
48template <class RandomNumberDistribution, class Generator>
50sample(std::size_t size, RandomNumberDistribution dist, Generator& g)
51{
53 std::ranges::generate(res, [&dist, &g]() { return dist(g); });
54 return res;
55}
56
65template <class RAIter, class Generator>
67{
68 RAIter first_, last_;
71
72public:
80 Selector(RAIter first, RAIter last, std::vector<double> const& w, Generator& g)
81 : first_{first}, last_{last}, dd_{w.begin(), w.end()}, g_{g}
82 {
84 static_assert(
86 "Selector only supports random access iterators.");
87 // TODO: Allow for forward iterators
88 }
89
92 {
93 auto idx = dd_(g_);
94 return *(first_ + idx);
95 }
96};
97
98template <typename Iter, typename Generator>
99Selector<Iter, Generator>
100makeSelector(Iter first, Iter last, std::vector<double> const& w, Generator& g)
101{
102 return Selector<Iter, Generator>(first, last, w, g);
103}
104
105//------------------------------------------------------------------------------
106// Additional distributions of interest not defined in <random>
107
112{
113 double t_;
114
115public:
116 ConstantDistribution(double const& t) : t_{t}
117 {
118 }
119
120 template <class Generator>
121 double
123 {
124 return t_;
125 }
126};
127
136{
137 double xmin_;
138 double a_;
139 double inv_{1.0 / (1.0 - a_)};
141
142public:
143 using result_type = double;
144
145 PowerLawDistribution(double xmin, double a) : xmin_{xmin}, a_{a}
146 {
147 }
148
149 template <class Generator>
150 double
152 {
153 // use inverse transform of CDF to sample
154 // CDF is P(X <= x): 1 - (x/xmin)^(1-a)
155 return xmin_ * std::pow(1 - uf_(g), inv_);
156 }
157};
158
159} // 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::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)