Visual Servoing Platform version 3.5.0
vpUniRand.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Pseudo random number generator.
33 *
34 *****************************************************************************/
35 /*
36 * PCG Random Number Generation for C.
37 *
38 * Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
39 *
40 * Licensed under the Apache License, Version 2.0 (the "License");
41 * you may not use this file except in compliance with the License.
42 * You may obtain a copy of the License at
43 *
44 * http://www.apache.org/licenses/LICENSE-2.0
45 *
46 * Unless required by applicable law or agreed to in writing, software
47 * distributed under the License is distributed on an "AS IS" BASIS,
48 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49 * See the License for the specific language governing permissions and
50 * limitations under the License.
51 *
52 * For additional information about the PCG random number generation scheme,
53 * including its license and other licensing options, visit
54 *
55 * http://www.pcg-random.org
56 */
57
58 /*
59 * This code is derived from the full C implementation, which is in turn
60 * derived from the canonical C++ PCG implementation. The C++ version
61 * has many additional features and is preferable if you can use C++ in
62 * your project.
63 */
64
65// To ensure UINT32_MAX, INT32_MX are defined on centos, ubuntu 12.04 we define __STDC_LIMIT_MACROS
66
67#define __STDC_LIMIT_MACROS
68
69#include <stdint.h>
70#include <visp3/core/vpUniRand.h>
71
73 m_maxInvDbl(1.0 / static_cast<double>(UINT32_MAX)), m_maxInvFlt(1.0f / static_cast<float>(UINT32_MAX)), m_rng()
74{
75}
76
85vpUniRand::vpUniRand(uint64_t seed, uint64_t seq) :
86 m_maxInvDbl(1.0 / static_cast<double>(UINT32_MAX)), m_maxInvFlt(1.0f / static_cast<float>(UINT32_MAX)), m_rng()
87{
88 setSeed(seed, seq);
89}
90
96{
97 return uniform(0.0, 1.0);
98}
99
112uint32_t vpUniRand::boundedRand(uint32_t bound)
113{
114 // To avoid bias, we need to make the range of the RNG a multiple of
115 // bound, which we do by dropping output less than a threshold.
116 // A naive scheme to calculate the threshold would be to do
117 //
118 // uint32_t threshold = 0x100000000ull % bound;
119 //
120 // but 64-bit div/mod is slower than 32-bit div/mod (especially on
121 // 32-bit platforms). In essence, we do
122 //
123 // uint32_t threshold = (0x100000000ull-bound) % bound;
124 //
125 // because this version will calculate the same modulus, but the LHS
126 // value is less than 2^32.
127
128 uint32_t threshold = -bound % bound;
129
130 // Uniformity guarantees that this loop will terminate. In practice, it
131 // should usually terminate quickly; on average (assuming all bounds are
132 // equally likely), 82.25% of the time, we can expect it to require just
133 // one iteration. In the worst case, someone passes a bound of 2^31 + 1
134 // (i.e., 2147483649), which invalidates almost 50% of the range. In
135 // practice, bounds are typically small and only a tiny amount of the range
136 // is eliminated.
137 for (;;) {
138 uint32_t r = next();
139 if (r >= threshold) {
140 return r % bound;
141 }
142 }
143}
144
150{
151 uint64_t oldstate = m_rng.state;
152 m_rng.state = oldstate * 6364136223846793005ULL + m_rng.inc;
153 uint32_t xorshifted = static_cast<uint32_t>(((oldstate >> 18u) ^ oldstate) >> 27u);
154 uint32_t rot = oldstate >> 59u;
155 return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
156}
157
163int vpUniRand::uniform(int a, int b)
164{
165 if (a == b) {
166 return a;
167 }
168 return boundedRand(b - a) + a;
169}
170
176float vpUniRand::uniform(float a, float b)
177{
178 return next()*m_maxInvFlt*(b - a) + a;
179}
180
186double vpUniRand::uniform(double a, double b)
187{
188 return next()*m_maxInvDbl*(b - a) + a;
189}
190
212void vpUniRand::setSeed(uint64_t initstate, uint64_t initseq)
213{
214 m_rng.state = 0U;
215 m_rng.inc = (initseq << 1u) | 1u;
216 next();
217 m_rng.state += initstate;
218 next();
219}
int uniform(int a, int b)
Definition: vpUniRand.cpp:163
uint32_t next()
Definition: vpUniRand.cpp:149
double operator()()
Definition: vpUniRand.cpp:95
void setSeed(uint64_t initstate, uint64_t initseq)
Definition: vpUniRand.cpp:212