Berkeley SfM
random_generator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, The Regents of the University of California (Regents).
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Please contact the author(s) of this library if you have any questions.
34  * Authors: Erik Nelson ( eanelson@eecs.berkeley.edu )
35  * David Fridovich-Keil ( dfk@eecs.berkeley.edu )
36  */
37 
38 #include "random_generator.h"
39 
40 namespace bsfm {
41 namespace math {
42 
43 RandomGenerator::RandomGenerator(unsigned long seed) {
44  srand(seed);
45 }
46 
47 unsigned long RandomGenerator::Seed() {
48  // Hash from: http://burtleburtle.net/bob/hash/doobs.html
49  // TODO(eanelson): Update this to read a seed from /dev/urandom instead.
50  unsigned long a = clock();
51  unsigned long b = time(NULL);
52  unsigned long c = getpid();
53  a-=b; a-=c; a^=(c >> 13); b-=c; b-=a; b^=(a << 8); c-=a; c-=b; c^=(b >> 13);
54  a-=b; a-=c; a^=(c >> 12); b-=c; b-=a; b^=(a << 16); c-=a; c-=b; c^=(b >> 5);
55  a-=b; a-=c; a^=(c >> 3); b-=c; b-=a; b^=(a << 10); c-=a; c-=b; c^=(b >> 15);
56  return c;
57 }
58 
59 
61  // TODO(eanelson: Use a threadsafe rng.
62  return rand();
63 }
64 
65 // Generates a random integer in [0, 'max').
67  if (max <= 0) {
68  LOG(WARNING) << "max <= 0. Returning 0.";
69  // Eat a random number anyways and return 0.
70  Integer();
71  return 0;
72  }
73 
74  return Integer() % static_cast<int>(max + 1);
75 }
76 
77 int RandomGenerator::IntegerUniform(int min, int max) {
78  if (min >= max) {
79  LOG(WARNING) << "min >= max. Returning min.";
80  // Eat a random number anyways and return min.
81  Integer();
82  return min;
83  }
84 
85  return min + (Integer() % static_cast<int>(max - min + 1));
86 }
87 
88 void RandomGenerator::Integers(size_t count, std::vector<int> *integers) {
89  if (integers == nullptr) {
90  return;
91  }
92 
93  for (size_t i = 0; i < count; ++i) {
94  integers->push_back(Integer());
95  }
96 }
97 
98 void RandomGenerator::IntegersUniform(size_t count, int min, int max,
99  std::vector<int>* integers) {
100  if (integers == nullptr) {
101  return;
102  }
103 
104  for (size_t i = 0; i < count; ++i) {
105  integers->push_back(IntegerUniform(min, max));
106  }
107 }
108 
110  return static_cast<double>(Integer()) / static_cast<double>(RAND_MAX);
111 }
112 
113 double RandomGenerator::DoubleUniform(double min, double max) {
114  if (min >= max) {
115  LOG(WARNING) << "min >= max. Returning min.";
116  // Eat a random number anyways and return min.
117  Integer();
118  return min;
119  }
120 
121  double coefficient = (max - min) / static_cast<double>(RAND_MAX);
122  return min + static_cast<double>(Integer()) * coefficient;
123 }
124 
125 double RandomGenerator::DoubleGaussian(double mean, double stddev) {
126  // Use the box-muller transform to approximate a normal distribution:
127  // https://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform
128  // u must be \in (0, 1], and v must be \in [0, 1).
129  double u = 1.0 - Double();
130  double v = Double();
131  double z = sqrt(-2.0 * log(u)) * cos(2.0 * M_PI * v);
132 
133  return mean + stddev * z;
134 }
135 
136 void RandomGenerator::Doubles(size_t count, std::vector<double>* doubles) {
137  if (doubles == nullptr) {
138  return;
139  }
140 
141  for (size_t i = 0; i < count; ++i) {
142  doubles->push_back(Double());
143  }
144 }
145 
146 void RandomGenerator::DoublesUniform(size_t count, double min, double max,
147  std::vector<double>* doubles) {
148  if (doubles == nullptr) {
149  return;
150  }
151 
152  for (size_t i = 0; i < count; ++i) {
153  doubles->push_back(DoubleUniform(min, max));
154  }
155 }
156 
157 void RandomGenerator::DoublesGaussian(size_t count, double mean, double stddev,
158  std::vector<double>* doubles) {
159  if (doubles == nullptr) {
160  return;
161  }
162 
163  for (size_t i = 0; i < count; ++i) {
164  doubles->push_back(DoubleGaussian(mean, stddev));
165  }
166 }
167 
168 } //\namespaces math
169 } //\namespace bsfm
double DoubleGaussian(double mean, double stddev)
void Integers(size_t count, std::vector< int > *integers)
void Doubles(size_t count, std::vector< double > *doubles)
void DoublesGaussian(size_t count, double mean, double stddev, std::vector< double > *doubles)
Definition: camera.cpp:50
void IntegersUniform(size_t count, int min, int max, std::vector< int > *integers)
double DoubleUniform(double min, double max)
void DoublesUniform(size_t count, double min, double max, std::vector< double > *doubles)
static unsigned long Seed()
RandomGenerator(unsigned long seed)