Honeycomb  0.1
Component-Model Framework
Random.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
8 
9 namespace honey
10 {
11 
13 namespace random
14 {
16  inline Bytes deviceEntropy(szt count) { return platform::deviceEntropy(count); }
17 }
18 
20 template<class Real>
21 class Random_
22 {
23  typedef typename Numeral<Real>::Real_ Real_;
24  typedef typename Real_::DoubleType Double_;
25  typedef typename Double_::Real Double;
26  typedef Random_<Double> Random_d;
27  typedef Alge_<Real> Alge;
28  typedef Alge_<Double> Alge_d;
29  typedef Interp_<Real> Interp;
30  typedef Uniform_<Real> Uniform;
32  typedef Gaussian_<Real> Gaussian;
33 
34  typedef Vec<2,Real> Vec2;
35  typedef Vec<3,Real> Vec3;
36  typedef Vec<4,Real> Vec4;
37  typedef Quat_<Real> Quat;
38 
39 public:
40  Random_() : _gen(nullptr) {}
42  Random_(RandomGen& gen) : _gen(&gen) {}
43 
45  void setGen(RandomGen& gen) { _gen = &gen; }
47  RandomGen& getGen() const { assert(_gen); return *_gen; }
48 
50  bool boolean() const { return (Discrete_<uint32>::nextStd(getGen()) & 1) == 1; }
51 
53  template<class T>
54  void sample(const vector<T>& list, szt count, vector<T>& sample) const
55  {
56  if (list.size() == 0) { sample.clear(); return; }
57  sample.resize(count);
58  for (szt i = 0; i < count; ++i)
59  sample[i] = list[Discrete_d(getGen(), 0, list.size()-1).next()];
60  }
61 
63  template<class T>
64  void choose(const vector<T>& list, szt count, vector<T>& chosen, vector<szt>& unchosen) const
65  {
66  szt chosenSize = Alge::min(count, list.size());
67  if (chosenSize == 0) { chosen.clear(); unchosen.clear(); return; }
68 
69  //Build unchosen index list
70  unchosen.resize(list.size());
71  for (szt i = 0; i < unchosen.size(); ++i) unchosen[i] = i;
72 
73  //Build chosen list
74  chosen.resize(chosenSize);
75  for (szt i = 0; i < chosenSize; ++i)
76  {
77  //Get random unchosen index and remove it
78  szt index = Discrete_d(getGen(), 0, unchosen.size() - 1).next();
79  chosen[i] = list[unchosen[index]];
80  unchosen.erase(unchosen.begin() + index);
81  }
82  }
83 
85  template<class T>
86  void shuffle(vector<T>& list) const
87  {
88  //Standard swap shuffle algorithm
89  for (szt i = list.size() - 1; i > 0; --i)
90  std::swap(list[i], list[Discrete_d(getGen(), 0, i).next()]);
91  }
92 
94  Vec3 dir() const;
95 
97  Vec3 dir(const Vec3& dir, Real dirVarMin, Real dirVarMax) const;
98 
100  Vec2 dir2d() const;
101 
103  template<class Range>
104  static tuple<Real,Real,Real> mean(const Range& samples)
105  {
106  auto res = reduce(samples, make_tuple(Real(0), Real_::inf, -Real_::inf),
107  [](tuple<Real,Real,Real> a, Real e) { return make_tuple(get<0>(a) + e, Alge::min(get<1>(a), e), Alge::max(get<2>(a), e)); });
108  szt n = end(samples) - begin(samples);
109  get<0>(res) = n > 0 ? get<0>(res) / n : 0;
110  return res;
111  }
112 
114  template<class Range>
115  static Real variance(const Range& samples, Real mean)
116  {
117  Real sumDev = reduce(samples, Real(0), [&](Real a, Real e) { return a + Alge::sqr(e - mean); });
118  szt n = end(samples) - begin(samples);
119  return n > 1 ? sumDev / (n-1) : 0;
120  }
121 
123  static Real stdDev(Real variance) { return Alge::sqrt(variance); }
124 
126  static Real stdErr(Real sampleSize, Real stddev) { return stddev / Alge::sqrt(sampleSize); }
127 
128  struct DistStats
129  {
130  szt n;
136 
137  friend ostream& operator<<(ostream& os, const DistStats& val)
138  {
139  return os << stringstream::indentInc << "{" << endl
140  << "N: " << val.n << endl
141  << "Mean: " << val.mean << endl
142  << "Min: " << val.min << endl
143  << "Max: " << val.max << endl
144  << "Std Dev: " << val.stdDev << endl
145  << "Std Err: " << val.stdErr
146  << stringstream::indentDec << endl << "}";
147  }
148  };
149 
151  template<class Range>
152  static DistStats stats(const Range& samples)
153  {
154  DistStats d;
155  d.n = end(samples) - begin(samples);
156  tie(d.mean, d.min, d.max) = mean(samples);
157  d.stdDev = stdDev(variance(samples, d.mean));
158  d.stdErr = stdErr(d.n, d.stdDev);
159  return d;
160  }
161 
162 private:
163  RandomGen* _gen;
164 };
165 
169 
170 extern template class Random_<Float>;
171 extern template class Random_<Double>;
172 
173 }
174 
Algebra.
Definition: Alge.h:13
void setGen(RandomGen &gen)
Set random generator to use for all methods.
Definition: Random.h:45
static Real variance(const Range &samples, Real mean)
Estimate the sample variance given the mean. This is the unbiased estimator (mean over all possible s...
Definition: Random.h:115
Random number generator interface.
Definition: Gen.h:11
Interpolation math.
Definition: Quat.h:10
void shuffle(vector< T > &list) const
Randomly permute a list. The entire list will be shuffled into a random order. All permutations have ...
Definition: Random.h:86
Accum reduce(Range &&, Seqs &&..., Accum &&initVal, Func &&)
Accumulate a series of sequences into an output.
static Real sqrt(Real x)
Square Root.
Definition: Alge.h:63
static std::common_type< Num, Num2 >::type max(Num a, Num2 b)
Get the maximum of two numbers.
Definition: Alge.h:94
Vec2 dir2d() const
Generate a 2D random unit direction.
Definition: Random.cpp:58
Random_< Real > Random
Definition: Random.h:166
Real min
Minimum sample value.
Definition: Random.h:132
static std::common_type< Num, Num2 >::type min(Num a, Num2 b)
Get the minimum of two numbers.
Definition: Alge.h:89
Real stdDev
Sample standard deviation.
Definition: Random.h:134
ostream & indentInc(ostream &os)
Increase stream indent level by 1.
Definition: Stream.h:32
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
ostream & indentDec(ostream &os)
Decrease stream indent level by 1.
Definition: Stream.h:34
Definition: Random.h:128
String of bytes.
Definition: Bytes.h:26
bool boolean() const
Generate random bool true/false.
Definition: Random.h:50
szt n
Sample size.
Definition: Random.h:130
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Numeric type information, use numeral() to get instance safely from a static context.
Definition: Numeral.h:17
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
Real stdErr
Standard error of the mean (ie. standard deviation of the sample-mean estimate of the population mean...
Definition: Random.h:135
Discrete_< int64 > Discrete_d
Definition: Discrete.h:52
static Real stdErr(Real sampleSize, Real stddev)
Calculate the standard error of the mean. This is how well the sample mean appoximates the population...
Definition: Random.h:126
Random_< Double > Random_d
Definition: Random.h:168
Real max
Maximum sample value.
Definition: Random.h:133
static DistStats stats(const Range &samples)
Calculate distribution statistics.
Definition: Random.h:152
double Real
Definition: Real.h:14
Vec3 dir() const
Generate a random unit direction.
Definition: Random.cpp:9
static Num sqr(Num x)
Square.
Definition: Alge.h:60
#define swap(a, i, j)
friend ostream & operator<<(ostream &os, const DistStats &val)
Definition: Random.h:137
Random_(RandomGen &gen)
Construct with random generator to use for all methods.
Definition: Random.h:42
Real mean
Sample mean.
Definition: Random.h:131
Bytes deviceEntropy(szt count)
Retrieve count bytes of entropy from the host device.
Definition: Random.h:16
Random_()
Definition: Random.h:40
Generate random integer variate between min and max inclusive with uniform (flat) distribution...
Definition: Discrete.h:20
Random-related methods.
Definition: Random.h:21
static Real stdDev(Real variance)
Calculate the standard deviation given the variance.
Definition: Random.h:123
void sample(const vector< T > &list, szt count, vector< T > &sample) const
Randomly choose count items from the list with replacement, so an item can be sampled more than once...
Definition: Random.h:54
void choose(const vector< T > &list, szt count, vector< T > &chosen, vector< szt > &unchosen) const
Randomly choose count items from a list without replacement, so an item can't be chosen more than onc...
Definition: Random.h:64
RandomGen & getGen() const
Get random generator.
Definition: Random.h:47
Generate a random variate between min and max non-inclusive with uniform (flat) distribution.
Definition: Dist.h:11
Generate a normally (Gaussian) distributed random variate.
Definition: Gaussian.h:26
static tuple< Real, Real, Real > mean(const Range &samples)
Estimate the sample mean, returns a tuple of (mean, min, max)
Definition: Random.h:104
ostream & endl(ostream &os)
End line and apply any indentation to the next line.
Definition: Stream.h:40
Global Honeycomb namespace.
Random_< Float > Random_f
Definition: Random.h:167