rippled
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 
26 namespace ripple {
27 namespace test {
28 namespace csf {
29 
39 template <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 
64 template <class RandomNumberDistribution, class Generator>
66 sample(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 
80 template <class RAIter, class Generator>
81 class Selector
82 {
83  RAIter first_, last_;
85  Generator g_;
86 
87 public:
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 
116 template <typename Iter, typename Generator>
117 Selector<Iter, Generator>
118 makeSelector(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 in <random>
125 
129 {
130  double t_;
131 
132 public:
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 
158 public:
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
std::is_same
ripple::test::csf::sample
std::vector< typename RandomNumberDistribution::result_type > sample(std::size_t size, RandomNumberDistribution dist, Generator &g)
Generate a vector of random samples.
Definition: test/csf/random.h:66
ripple::test::csf::makeSelector
Selector< Iter, Generator > makeSelector(Iter first, Iter last, std::vector< double > const &w, Generator &g)
Definition: test/csf/random.h:118
ripple::test::csf::PowerLawDistribution::uf_
std::uniform_real_distribution< double > uf_
Definition: test/csf/random.h:156
std::discrete_distribution
ripple::test::csf::Selector
Invocable that returns random samples from a range according to a discrete distribution.
Definition: test/csf/random.h:81
vector
std::vector::size
T size(T... args)
ripple::test::csf::PowerLawDistribution::PowerLawDistribution
PowerLawDistribution(double xmin, double a)
Definition: test/csf/random.h:161
random
ripple::test::csf::Selector::first_
RAIter first_
Definition: test/csf/random.h:83
ripple::test::csf::random_weighted_shuffle
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.
Definition: test/csf/random.h:41
std::generate
T generate(T... args)
ripple::test::csf::PowerLawDistribution::xmin_
double xmin_
Definition: test/csf/random.h:153
ripple::test::csf::Selector::dd_
std::discrete_distribution dd_
Definition: test/csf/random.h:84
std::uniform_real_distribution< double >
ripple::test::csf::PowerLawDistribution::inv_
double inv_
Definition: test/csf/random.h:155
ripple::test::csf::ConstantDistribution::operator()
double operator()(Generator &)
Definition: test/csf/random.h:139
std::iterator_traits
ripple::test::csf::PowerLawDistribution::a_
double a_
Definition: test/csf/random.h:154
ripple::test::csf::PowerLawDistribution
Power-law distribution with PDF.
Definition: test/csf/random.h:151
ripple::test::csf::PowerLawDistribution::operator()
double operator()(Generator &g)
Definition: test/csf/random.h:168
ripple::test::csf::ConstantDistribution::ConstantDistribution
ConstantDistribution(double const &t)
Definition: test/csf/random.h:133
std::swap
T swap(T... args)
ripple::test::csf::ConstantDistribution
Constant "distribution" that always returns the same value.
Definition: test/csf/random.h:128
ripple::test::csf::Selector::operator()
std::iterator_traits< RAIter >::value_type operator()()
Definition: test/csf/random.h:109
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::csf::PowerLawDistribution::result_type
double result_type
Definition: test/csf/random.h:159
std::vector::begin
T begin(T... args)
ripple::test::csf::Selector::Selector
Selector(RAIter first, RAIter last, std::vector< double > const &w, Generator &g)
Constructor.
Definition: test/csf/random.h:94
std::size_t
std::vector::end
T end(T... args)
ripple::test::csf::ConstantDistribution::t_
double t_
Definition: test/csf/random.h:130
ripple::test::csf::Selector::g_
Generator g_
Definition: test/csf/random.h:85
ripple::test::csf::Selector::last_
RAIter last_
Definition: test/csf/random.h:83
std::pow
T pow(T... args)