rippled
Loading...
Searching...
No Matches
src/test/csf/random.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2017 Ripple Labs Inc
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_TEST_CSF_RANDOM_H_INCLUDED
21#define RIPPLE_TEST_CSF_RANDOM_H_INCLUDED
22
23#include <random>
24#include <vector>
25
26namespace ripple {
27namespace test {
28namespace csf {
29
39template <class T, class G>
42{
43 using std::swap;
44
45 for (int i = 0; i < v.size() - 1; ++i)
46 {
47 // pick a random item weighted by w
48 std::discrete_distribution<> dd(w.begin() + i, w.end());
49 auto idx = dd(g);
50 std::swap(v[i], v[idx]);
51 std::swap(w[i], w[idx]);
52 }
53 return v;
54}
55
64template <class RandomNumberDistribution, class Generator>
66sample(std::size_t size, RandomNumberDistribution dist, Generator& g)
67{
69 std::generate(res.begin(), res.end(), [&dist, &g]() { return dist(g); });
70 return res;
71}
72
80template <class RAIter, class Generator>
82{
83 RAIter first_, last_;
85 Generator g_;
86
87public:
95 RAIter first,
96 RAIter last,
97 std::vector<double> const& w,
98 Generator& g)
99 : first_{first}, last_{last}, dd_{w.begin(), w.end()}, g_{g}
100 {
102 static_assert(
104 "Selector only supports random access iterators.");
105 // TODO: Allow for forward iterators
106 }
107
110 {
111 auto idx = dd_(g_);
112 return *(first_ + idx);
113 }
114};
115
116template <typename Iter, typename Generator>
117Selector<Iter, Generator>
118makeSelector(Iter first, Iter last, std::vector<double> const& w, Generator& g)
119{
120 return Selector<Iter, Generator>(first, last, w, g);
121}
122
123//------------------------------------------------------------------------------
124// Additional distributions of interest not defined in <random>
125
129{
130 double t_;
131
132public:
133 ConstantDistribution(double const& t) : t_{t}
134 {
135 }
136
137 template <class Generator>
138 inline double
139 operator()(Generator&)
140 {
141 return t_;
142 }
143};
144
152{
153 double xmin_;
154 double a_;
155 double inv_;
157
158public:
159 using result_type = double;
160
161 PowerLawDistribution(double xmin, double a) : xmin_{xmin}, a_{a}
162 {
163 inv_ = 1.0 / (1.0 - a_);
164 }
165
166 template <class Generator>
167 inline double
168 operator()(Generator& g)
169 {
170 // use inverse transform of CDF to sample
171 // CDF is P(X <= x): 1 - (x/xmin)^(1-a)
172 return xmin_ * std::pow(1 - uf_(g), inv_);
173 }
174};
175
176} // namespace csf
177} // namespace test
178} // namespace ripple
179
180#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:25
T pow(T... args)
T size(T... args)
T swap(T... args)