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