LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
numpy_random_state.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012-2026, QORE Lab, Imperial College London
3
* All rights reserved.
4
*/
5
#ifndef LINE_OPT_DE_NUMPY_RANDOM_STATE_H
6
#define LINE_OPT_DE_NUMPY_RANDOM_STATE_H
7
8
/**
9
* @file
10
* @ingroup line_opt
11
* Bit-exact port of `matlab/src/opt/+opt/+de/NumpyRandomState.m`.
12
*
13
* Only the legacy NumPy RandomState operations consumed by line-opt are
14
* exposed: random_sample, uniform, default-dtype randint, shuffle and
15
* permutation. Their word consumption is part of the contract.
16
*/
17
18
#include <algorithm>
19
#include <cstddef>
20
#include <cstdint>
21
#include <numeric>
22
#include <vector>
23
24
#include "
line/opt/de/mt19937.h
"
25
#include "
line/util/error.h
"
26
27
namespace
line
{
28
namespace
opt
{
29
namespace
de
{
30
31
class
NumpyRandomState
{
32
public
:
33
explicit
NumpyRandomState
(std::uint64_t seed) : gen_(seed) {}
34
35
MT19937
&
generator
() {
return
gen_; }
36
const
MT19937
&
generator
()
const
{
return
gen_; }
37
38
/** NumPy `random_sample()`: one 53-bit double from two generator words. */
39
double
random_sample
() {
40
const
std::uint64_t a =
static_cast<
std::uint64_t
>
(gen_.next_uint32() >> 5);
41
const
std::uint64_t b =
static_cast<
std::uint64_t
>
(gen_.next_uint32() >> 6);
42
return
(
static_cast<
double
>
(a) * 67108864.0 +
static_cast<
double
>
(b)) /
43
9007199254740992.0;
44
}
45
46
std::vector<double>
random_sample
(std::size_t n) {
47
std::vector<double> out(n);
48
for
(
double
& value : out) value =
random_sample
();
49
return
out;
50
}
51
52
double
uniform
(
double
low = 0.0,
double
high = 1.0) {
53
return
low + (high - low) *
random_sample
();
54
}
55
56
std::vector<double>
uniform
(
double
low,
double
high, std::size_t n) {
57
std::vector<double> out(n);
58
for
(
double
& value : out) value = low + (high - low) *
random_sample
();
59
return
out;
60
}
61
62
std::uint64_t
randint
(std::uint64_t low, std::uint64_t high) {
63
if
(high <= low)
throw
InputError
(
"NumpyRandomState::randint: high must exceed low"
);
64
const
std::uint64_t range = high - 1 - low;
65
if
(range > UINT64_C(0xffffffff))
66
throw
InputError
(
67
"NumpyRandomState::randint: the line-opt RandomState subset uses 32-bit ranges"
);
68
if
(range == 0)
return
low;
69
const
std::uint64_t mask = fill_mask(range);
70
for
(;;) {
71
const
std::uint64_t value =
static_cast<
std::uint64_t
>
(gen_.next_uint32()) & mask;
72
if
(value <= range)
return
low + value;
73
}
74
}
75
76
std::uint64_t
randint
(std::uint64_t high) {
return
randint
(0, high); }
77
78
std::uint64_t
random_interval
(std::uint64_t max_value) {
79
if
(max_value > UINT64_C(0xffffffff))
80
throw
InputError
(
"NumpyRandomState::random_interval: max exceeds 32 bits"
);
81
if
(max_value == 0)
return
0;
82
const
std::uint64_t mask = fill_mask(max_value);
83
for
(;;) {
84
const
std::uint64_t value =
static_cast<
std::uint64_t
>
(gen_.next_uint32()) & mask;
85
if
(value <= max_value)
return
value;
86
}
87
}
88
89
template
<
class
T>
90
void
shuffle
(std::vector<T>& values) {
91
for
(std::size_t p = values.size(); p > 1; --p) {
92
const
std::size_t j =
static_cast<
std::size_t
>
(
random_interval
(p - 1));
93
std::swap(values[p - 1], values[j]);
94
}
95
}
96
97
std::vector<std::size_t>
permutation
(std::size_t n) {
98
std::vector<std::size_t> out(n);
99
std::iota(out.begin(), out.end(), std::size_t(0));
100
shuffle
(out);
101
return
out;
102
}
103
104
private
:
105
static
std::uint64_t fill_mask(std::uint64_t value) {
106
value |= value >> 1;
107
value |= value >> 2;
108
value |= value >> 4;
109
value |= value >> 8;
110
value |= value >> 16;
111
return
value;
112
}
113
114
MT19937 gen_;
115
};
116
117
}
// namespace de
118
}
// namespace opt
119
}
// namespace line
120
121
#endif
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::opt::de::MT19937
Definition
mt19937.h:31
line::opt::de::NumpyRandomState::permutation
std::vector< std::size_t > permutation(std::size_t n)
Definition
numpy_random_state.h:97
line::opt::de::NumpyRandomState::shuffle
void shuffle(std::vector< T > &values)
Definition
numpy_random_state.h:90
line::opt::de::NumpyRandomState::uniform
std::vector< double > uniform(double low, double high, std::size_t n)
Definition
numpy_random_state.h:56
line::opt::de::NumpyRandomState::random_sample
double random_sample()
NumPy random_sample(): one 53-bit double from two generator words.
Definition
numpy_random_state.h:39
line::opt::de::NumpyRandomState::random_interval
std::uint64_t random_interval(std::uint64_t max_value)
Definition
numpy_random_state.h:78
line::opt::de::NumpyRandomState::generator
MT19937 & generator()
Definition
numpy_random_state.h:35
line::opt::de::NumpyRandomState::generator
const MT19937 & generator() const
Definition
numpy_random_state.h:36
line::opt::de::NumpyRandomState::randint
std::uint64_t randint(std::uint64_t high)
Definition
numpy_random_state.h:76
line::opt::de::NumpyRandomState::randint
std::uint64_t randint(std::uint64_t low, std::uint64_t high)
Definition
numpy_random_state.h:62
line::opt::de::NumpyRandomState::NumpyRandomState
NumpyRandomState(std::uint64_t seed)
Definition
numpy_random_state.h:33
line::opt::de::NumpyRandomState::random_sample
std::vector< double > random_sample(std::size_t n)
Definition
numpy_random_state.h:46
line::opt::de::NumpyRandomState::uniform
double uniform(double low=0.0, double high=1.0)
Definition
numpy_random_state.h:52
error.h
The exception types the port throws.
mt19937.h
Bit-exact port of matlab/src/opt/+opt/+de/MT19937.m.
line::opt::de
Definition
differential_evolution.h:37
line::opt
Definition
bisection_solver.h:31
line
Definition
aoi_dist2ph.h:52
include
line
opt
de
numpy_random_state.h
Generated by
1.18.0