isotree 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -1
- data/LICENSE.txt +2 -2
- data/README.md +32 -14
- data/ext/isotree/ext.cpp +144 -31
- data/ext/isotree/extconf.rb +7 -7
- data/lib/isotree/isolation_forest.rb +110 -30
- data/lib/isotree/version.rb +1 -1
- data/vendor/isotree/LICENSE +1 -1
- data/vendor/isotree/README.md +165 -27
- data/vendor/isotree/include/isotree.hpp +2111 -0
- data/vendor/isotree/include/isotree_oop.hpp +394 -0
- data/vendor/isotree/inst/COPYRIGHTS +62 -0
- data/vendor/isotree/src/RcppExports.cpp +525 -52
- data/vendor/isotree/src/Rwrapper.cpp +1931 -268
- data/vendor/isotree/src/c_interface.cpp +953 -0
- data/vendor/isotree/src/crit.hpp +4232 -0
- data/vendor/isotree/src/dist.hpp +1886 -0
- data/vendor/isotree/src/exp_depth_table.hpp +134 -0
- data/vendor/isotree/src/extended.hpp +1444 -0
- data/vendor/isotree/src/external_facing_generic.hpp +399 -0
- data/vendor/isotree/src/fit_model.hpp +2401 -0
- data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
- data/vendor/isotree/src/helpers_iforest.hpp +813 -0
- data/vendor/isotree/src/{impute.cpp → impute.hpp} +353 -122
- data/vendor/isotree/src/indexer.cpp +515 -0
- data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
- data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
- data/vendor/isotree/src/isoforest.hpp +1659 -0
- data/vendor/isotree/src/isotree.hpp +1804 -392
- data/vendor/isotree/src/isotree_exportable.hpp +99 -0
- data/vendor/isotree/src/merge_models.cpp +159 -16
- data/vendor/isotree/src/mult.hpp +1321 -0
- data/vendor/isotree/src/oop_interface.cpp +842 -0
- data/vendor/isotree/src/oop_interface.hpp +278 -0
- data/vendor/isotree/src/other_helpers.hpp +219 -0
- data/vendor/isotree/src/predict.hpp +1932 -0
- data/vendor/isotree/src/python_helpers.hpp +134 -0
- data/vendor/isotree/src/ref_indexer.hpp +154 -0
- data/vendor/isotree/src/robinmap/LICENSE +21 -0
- data/vendor/isotree/src/robinmap/README.md +483 -0
- data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
- data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1620 -0
- data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
- data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
- data/vendor/isotree/src/serialize.cpp +4300 -139
- data/vendor/isotree/src/sql.cpp +141 -59
- data/vendor/isotree/src/subset_models.cpp +174 -0
- data/vendor/isotree/src/utils.hpp +3808 -0
- data/vendor/isotree/src/xoshiro.hpp +467 -0
- data/vendor/isotree/src/ziggurat.hpp +405 -0
- metadata +38 -104
- data/vendor/cereal/LICENSE +0 -24
- data/vendor/cereal/README.md +0 -85
- data/vendor/cereal/include/cereal/access.hpp +0 -351
- data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
- data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
- data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
- data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
- data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
- data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
- data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
- data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
- data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
- data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
- data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
- data/vendor/cereal/include/cereal/details/util.hpp +0 -84
- data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
- data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
- data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
- data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
- data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
- data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
- data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
- data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
- data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
- data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
- data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
- data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
- data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
- data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
- data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
- data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
- data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
- data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
- data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
- data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
- data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
- data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
- data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
- data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
- data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
- data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
- data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
- data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
- data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
- data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
- data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
- data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
- data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
- data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
- data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
- data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
- data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
- data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
- data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
- data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
- data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
- data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
- data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
- data/vendor/cereal/include/cereal/macros.hpp +0 -154
- data/vendor/cereal/include/cereal/specialize.hpp +0 -139
- data/vendor/cereal/include/cereal/types/array.hpp +0 -79
- data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
- data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
- data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
- data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
- data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
- data/vendor/cereal/include/cereal/types/common.hpp +0 -129
- data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
- data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
- data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
- data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
- data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
- data/vendor/cereal/include/cereal/types/list.hpp +0 -62
- data/vendor/cereal/include/cereal/types/map.hpp +0 -36
- data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
- data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
- data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
- data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
- data/vendor/cereal/include/cereal/types/set.hpp +0 -103
- data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
- data/vendor/cereal/include/cereal/types/string.hpp +0 -61
- data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
- data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
- data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
- data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
- data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
- data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
- data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
- data/vendor/cereal/include/cereal/version.hpp +0 -52
- data/vendor/isotree/src/Makevars +0 -4
- data/vendor/isotree/src/crit.cpp +0 -912
- data/vendor/isotree/src/dist.cpp +0 -749
- data/vendor/isotree/src/extended.cpp +0 -790
- data/vendor/isotree/src/fit_model.cpp +0 -1090
- data/vendor/isotree/src/helpers_iforest.cpp +0 -324
- data/vendor/isotree/src/isoforest.cpp +0 -771
- data/vendor/isotree/src/mult.cpp +0 -607
- data/vendor/isotree/src/predict.cpp +0 -853
- data/vendor/isotree/src/utils.cpp +0 -1566
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
/* This file was taken from here:
|
|
2
|
+
https://prng.di.unimi.it
|
|
3
|
+
And adapted as needed for inclusion into IsoTree */
|
|
4
|
+
|
|
5
|
+
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
|
6
|
+
|
|
7
|
+
To the extent possible under law, the author has dedicated all copyright
|
|
8
|
+
and related and neighboring rights to this software to the public domain
|
|
9
|
+
worldwide. This software is distributed without any warranty.
|
|
10
|
+
|
|
11
|
+
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|
12
|
+
#include <cstdint>
|
|
13
|
+
#include <cstring>
|
|
14
|
+
#if (__cplusplus >= 202002L)
|
|
15
|
+
#include <bit>
|
|
16
|
+
#endif
|
|
17
|
+
using std::uint8_t;
|
|
18
|
+
using std::uint32_t;
|
|
19
|
+
using std::uint64_t;
|
|
20
|
+
using std::memcpy;
|
|
21
|
+
|
|
22
|
+
#ifndef _FOR_R
|
|
23
|
+
#if defined(__clang__)
|
|
24
|
+
#pragma clang diagnostic push
|
|
25
|
+
#pragma clang diagnostic ignored "-Wunknown-attributes"
|
|
26
|
+
#endif
|
|
27
|
+
#endif
|
|
28
|
+
|
|
29
|
+
#if (__cplusplus >= 201703L) || (__cplusplus >= 201402L && (defined(__GNUC__) || defined(_MSC_VER)))
|
|
30
|
+
#define SUPPORTS_HEXFLOAT
|
|
31
|
+
#endif
|
|
32
|
+
|
|
33
|
+
namespace Xoshiro {
|
|
34
|
+
|
|
35
|
+
#if (__cplusplus >= 202002L)
|
|
36
|
+
#define rotl64(x, k) std::rotl(x, k)
|
|
37
|
+
#define rotl32(x, k) std::rotl(x, k)
|
|
38
|
+
#else
|
|
39
|
+
static inline uint64_t rotl64(const uint64_t x, const int k) noexcept {
|
|
40
|
+
return (x << k) | (x >> (64 - k));
|
|
41
|
+
}
|
|
42
|
+
static inline uint32_t rotl32(const uint32_t x, const int k) noexcept {
|
|
43
|
+
return (x << k) | (x >> (32 - k));
|
|
44
|
+
}
|
|
45
|
+
#endif
|
|
46
|
+
|
|
47
|
+
/* these are in order to avoid gcc warnings about 'strict aliasing rules' */
|
|
48
|
+
static inline uint32_t extract_32bits_from64_left(const uint64_t x) noexcept
|
|
49
|
+
{
|
|
50
|
+
uint32_t out;
|
|
51
|
+
memcpy(reinterpret_cast<char*>(&out),
|
|
52
|
+
reinterpret_cast<const char*>(&x),
|
|
53
|
+
sizeof(uint32_t));
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static inline uint32_t extract_32bits_from64_right(const uint64_t x) noexcept
|
|
58
|
+
{
|
|
59
|
+
uint32_t out;
|
|
60
|
+
memcpy(reinterpret_cast<char*>(&out),
|
|
61
|
+
reinterpret_cast<const char*>(&x) + sizeof(uint32_t),
|
|
62
|
+
sizeof(uint32_t));
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static inline void assign_32bits_to64_left(uint64_t &assign_to, const uint32_t take_from) noexcept
|
|
67
|
+
{
|
|
68
|
+
memcpy(reinterpret_cast<char*>(&assign_to),
|
|
69
|
+
reinterpret_cast<const char*>(&take_from),
|
|
70
|
+
sizeof(uint32_t));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
static inline void assign_32bits_to64_right(uint64_t &assign_to, const uint32_t take_from) noexcept
|
|
74
|
+
{
|
|
75
|
+
memcpy(reinterpret_cast<char*>(&assign_to) + sizeof(uint32_t),
|
|
76
|
+
reinterpret_cast<const char*>(&take_from),
|
|
77
|
+
sizeof(uint32_t));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* This is a fixed-increment version of Java 8's SplittableRandom generator
|
|
81
|
+
See http://dx.doi.org/10.1145/2714064.2660195 and
|
|
82
|
+
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
|
|
83
|
+
|
|
84
|
+
It is a very fast generator passing BigCrush, and it can be useful if
|
|
85
|
+
for some reason you absolutely want 64 bits of state. */
|
|
86
|
+
static inline uint64_t splitmix64(const uint64_t seed) noexcept
|
|
87
|
+
{
|
|
88
|
+
uint64_t z = (seed + 0x9e3779b97f4a7c15);
|
|
89
|
+
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
|
|
90
|
+
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
|
|
91
|
+
return z ^ (z >> 31);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
|
|
95
|
+
It has excellent (sub-ns) speed, a state (256 bits) that is large
|
|
96
|
+
enough for any parallel application, and it passes all tests we are
|
|
97
|
+
aware of.
|
|
98
|
+
|
|
99
|
+
For generating just floating-point numbers, xoshiro256+ is even faster.
|
|
100
|
+
|
|
101
|
+
The state must be seeded so that it is not everywhere zero. If you have
|
|
102
|
+
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
|
103
|
+
output to fill s. */
|
|
104
|
+
class Xoshiro256PP
|
|
105
|
+
{
|
|
106
|
+
public:
|
|
107
|
+
using result_type = uint64_t;
|
|
108
|
+
uint64_t state[4];
|
|
109
|
+
|
|
110
|
+
constexpr static result_type min() noexcept
|
|
111
|
+
{
|
|
112
|
+
return 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
constexpr static result_type max() noexcept
|
|
116
|
+
{
|
|
117
|
+
return UINT64_MAX;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
Xoshiro256PP() noexcept = default;
|
|
121
|
+
|
|
122
|
+
inline void seed(const uint64_t seed) noexcept
|
|
123
|
+
{
|
|
124
|
+
this->state[0] = splitmix64(splitmix64(seed));
|
|
125
|
+
this->state[1] = splitmix64(this->state[0]);
|
|
126
|
+
this->state[2] = splitmix64(this->state[1]);
|
|
127
|
+
this->state[3] = splitmix64(this->state[2]);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
template <class integer>
|
|
131
|
+
inline void seed(const integer seed) noexcept
|
|
132
|
+
{
|
|
133
|
+
this->seed((uint64_t)seed);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
Xoshiro256PP(const uint64_t seed) noexcept
|
|
137
|
+
{
|
|
138
|
+
this->seed(seed);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
template <class integer>
|
|
142
|
+
Xoshiro256PP(const integer seed) noexcept
|
|
143
|
+
{
|
|
144
|
+
this->seed((uint64_t)seed);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
inline result_type operator()() noexcept
|
|
148
|
+
{
|
|
149
|
+
const uint64_t result = rotl64(this->state[0] + this->state[3], 23) + this->state[0];
|
|
150
|
+
const uint64_t t = this->state[1] << 17;
|
|
151
|
+
this->state[2] ^= this->state[0];
|
|
152
|
+
this->state[3] ^= this->state[1];
|
|
153
|
+
this->state[1] ^= this->state[2];
|
|
154
|
+
this->state[0] ^= this->state[3];
|
|
155
|
+
this->state[2] ^= t;
|
|
156
|
+
this->state[3] = rotl64(this->state[3], 45);
|
|
157
|
+
return result;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
|
|
162
|
+
generators. It has excellent speed, a state size (128 bits) that is
|
|
163
|
+
large enough for mild parallelism, and it passes all tests we are aware
|
|
164
|
+
of.
|
|
165
|
+
|
|
166
|
+
For generating just single-precision (i.e., 32-bit) floating-point
|
|
167
|
+
numbers, xoshiro128+ is even faster.
|
|
168
|
+
|
|
169
|
+
The state must be seeded so that it is not everywhere zero. */
|
|
170
|
+
class Xoshiro128PP
|
|
171
|
+
{
|
|
172
|
+
public:
|
|
173
|
+
using result_type = uint32_t;
|
|
174
|
+
uint32_t state[4];
|
|
175
|
+
|
|
176
|
+
constexpr static result_type min() noexcept
|
|
177
|
+
{
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
constexpr static result_type max() noexcept
|
|
182
|
+
{
|
|
183
|
+
return UINT32_MAX;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
Xoshiro128PP() noexcept = default;
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
inline void seed(const uint64_t seed) noexcept
|
|
190
|
+
{
|
|
191
|
+
const auto t1 = splitmix64(seed);
|
|
192
|
+
const auto t2 = splitmix64(t1);
|
|
193
|
+
this->state[0] = extract_32bits_from64_left(t1);
|
|
194
|
+
this->state[1] = extract_32bits_from64_right(t1);
|
|
195
|
+
this->state[2] = extract_32bits_from64_left(t2);
|
|
196
|
+
this->state[3] = extract_32bits_from64_right(t2);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
inline void seed(const uint32_t seed) noexcept
|
|
200
|
+
{
|
|
201
|
+
uint64_t temp;
|
|
202
|
+
assign_32bits_to64_left(temp, seed);
|
|
203
|
+
assign_32bits_to64_right(temp, seed);
|
|
204
|
+
this->seed(temp);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
template <class integer>
|
|
209
|
+
inline void seed(const integer seed) noexcept
|
|
210
|
+
{
|
|
211
|
+
this->seed((uint64_t)seed);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
Xoshiro128PP(const uint32_t seed) noexcept
|
|
215
|
+
{
|
|
216
|
+
this->seed(seed);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
Xoshiro128PP(const uint64_t seed) noexcept
|
|
220
|
+
{
|
|
221
|
+
this->seed(seed);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
template <class integer>
|
|
225
|
+
Xoshiro128PP(const integer seed) noexcept
|
|
226
|
+
{
|
|
227
|
+
this->seed((uint64_t)seed);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
inline result_type operator()() noexcept
|
|
231
|
+
{
|
|
232
|
+
const uint32_t result = rotl32(this->state[0] + this->state[3], 7) + this->state[0];
|
|
233
|
+
const uint32_t t = this->state[1] << 9;
|
|
234
|
+
this->state[2] ^= this->state[0];
|
|
235
|
+
this->state[3] ^= this->state[1];
|
|
236
|
+
this->state[1] ^= this->state[2];
|
|
237
|
+
this->state[0] ^= this->state[3];
|
|
238
|
+
this->state[2] ^= t;
|
|
239
|
+
this->state[3] = rotl32(this->state[3], 11);
|
|
240
|
+
return result;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
#ifndef M_PI
|
|
245
|
+
#define M_PI 3.14159265358979323846
|
|
246
|
+
#endif
|
|
247
|
+
|
|
248
|
+
constexpr static const uint64_t two53_i = (UINT64_C(1) << 53) - UINT64_C(1);
|
|
249
|
+
constexpr static const int64_t two53_ii = (INT64_C(1) << 53);
|
|
250
|
+
constexpr static const uint64_t two54_i = (UINT64_C(1) << 54) - UINT64_C(1);
|
|
251
|
+
constexpr static const uint64_t two52i = (UINT64_C(1) << 52) - UINT64_C(1);
|
|
252
|
+
constexpr static const uint32_t two22_i = (UINT32_C(1) << 22) - UINT32_C(1);
|
|
253
|
+
constexpr static const uint32_t two21_i = (UINT32_C(1) << 21) - UINT32_C(1);
|
|
254
|
+
constexpr static const uint32_t two20_i = (UINT32_C(1) << 20) - UINT32_C(1);
|
|
255
|
+
constexpr static const double ui64_d = (double)UINT64_MAX;
|
|
256
|
+
constexpr static const double i64_d = (double)INT64_MAX;
|
|
257
|
+
constexpr static const double twoPI = 2. * M_PI;
|
|
258
|
+
|
|
259
|
+
[[gnu::flatten, gnu::always_inline]]
|
|
260
|
+
static inline uint64_t gen_bits(Xoshiro256PP &rng) noexcept
|
|
261
|
+
{
|
|
262
|
+
return rng();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
[[gnu::flatten, gnu::always_inline]]
|
|
266
|
+
static inline uint64_t gen_bits(Xoshiro128PP &rng) noexcept
|
|
267
|
+
{
|
|
268
|
+
uint64_t bits;
|
|
269
|
+
assign_32bits_to64_left(bits, rng());
|
|
270
|
+
assign_32bits_to64_right(bits, rng());
|
|
271
|
+
return bits;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
/* Note: the way in which endian-ness detection is handled here looks
|
|
276
|
+
inefficient at a first glance. Nevertheless, do NOT try to optimize
|
|
277
|
+
any further as GCC9 has a bug in which it optimizes away some 'if's'
|
|
278
|
+
but with the *wrong* bit ending if done as ternary operators or if
|
|
279
|
+
declaring pointer variables outside of the braces in what comes below. */
|
|
280
|
+
static inline bool get_is_little_endian() noexcept
|
|
281
|
+
{
|
|
282
|
+
const uint32_t ONE = 1;
|
|
283
|
+
return (*(reinterpret_cast<const unsigned char*>(&ONE)) != 0);
|
|
284
|
+
}
|
|
285
|
+
static const bool is_little_endian = get_is_little_endian();
|
|
286
|
+
|
|
287
|
+
/* ~Uniform([0,1))
|
|
288
|
+
Be aware that the compilers headers may:
|
|
289
|
+
- Produce a non-uniform distribution as they divide
|
|
290
|
+
by the maximum value of the generator (not all numbers
|
|
291
|
+
between zero and one are representable).
|
|
292
|
+
- Draw from a closed interval [0,1] (infinitesimal chance
|
|
293
|
+
that something will go wrong, but better not take it).
|
|
294
|
+
(For example, GCC4 had bugs like those)
|
|
295
|
+
Hence this replacement. It is not too much slower
|
|
296
|
+
than what the compiler's header use. */
|
|
297
|
+
class UniformUnitInterval
|
|
298
|
+
{
|
|
299
|
+
public:
|
|
300
|
+
UniformUnitInterval() noexcept = default;
|
|
301
|
+
|
|
302
|
+
template <class A, class B>
|
|
303
|
+
UniformUnitInterval(A a, B b) noexcept {}
|
|
304
|
+
|
|
305
|
+
template <class XoshiroRNG>
|
|
306
|
+
#ifndef _FOR_R
|
|
307
|
+
[[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
|
|
308
|
+
#endif
|
|
309
|
+
double operator()(XoshiroRNG &rng) noexcept
|
|
310
|
+
{
|
|
311
|
+
#if SIZE_MAX >= UINT64_MAX
|
|
312
|
+
# ifdef SUPPORTS_HEXFLOAT
|
|
313
|
+
return (double)(gen_bits(rng) >> 11) * 0x1.0p-53;
|
|
314
|
+
# else
|
|
315
|
+
return std::ldexp(gen_bits(rng) >> 11, -53);
|
|
316
|
+
# endif
|
|
317
|
+
#else
|
|
318
|
+
uint64_t bits = gen_bits(rng);
|
|
319
|
+
char *rbits_ = reinterpret_cast<char*>(&bits);
|
|
320
|
+
if (is_little_endian) rbits_ += sizeof(uint32_t);
|
|
321
|
+
uint32_t rbits;
|
|
322
|
+
memcpy(&rbits, rbits_, sizeof(uint32_t));
|
|
323
|
+
rbits = rbits & two21_i;
|
|
324
|
+
memcpy(rbits_, &rbits, sizeof(uint32_t));
|
|
325
|
+
# ifdef SUPPORTS_HEXFLOAT
|
|
326
|
+
return (double)bits * 0x1.0p-53;
|
|
327
|
+
# else
|
|
328
|
+
return std::ldexp(bits, -53);
|
|
329
|
+
#endif
|
|
330
|
+
#endif
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
/* Note: this should sample in an open interval [-1,1].
|
|
335
|
+
It's however quite hard to sample uniformly in an open
|
|
336
|
+
interval with floating point numbers, since it'd require
|
|
337
|
+
drawing a random number up to a power of 2 plus one, which
|
|
338
|
+
does not translate into the required precision with
|
|
339
|
+
increments of 2^n that IEEE754 floats have around the unit
|
|
340
|
+
interval. Nevertheless, since it'd be less than ideal to
|
|
341
|
+
output zero from here (that is, it would mean not taking
|
|
342
|
+
a column when creating a random hyperplane), it instead
|
|
343
|
+
will transform exact zeros into exact ones. */
|
|
344
|
+
class UniformMinusOneToOne
|
|
345
|
+
{
|
|
346
|
+
public:
|
|
347
|
+
UniformMinusOneToOne() noexcept = default;
|
|
348
|
+
|
|
349
|
+
template <class A, class B>
|
|
350
|
+
UniformMinusOneToOne(A a, B b) noexcept {}
|
|
351
|
+
|
|
352
|
+
template <class XoshiroRNG>
|
|
353
|
+
#ifndef _FOR_R
|
|
354
|
+
[[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
|
|
355
|
+
#endif
|
|
356
|
+
double operator()(XoshiroRNG &rng) noexcept
|
|
357
|
+
{
|
|
358
|
+
#if SIZE_MAX >= UINT64_MAX
|
|
359
|
+
# ifdef SUPPORTS_HEXFLOAT
|
|
360
|
+
double out = (double)((int64_t)(gen_bits(rng) >> 10) - two53_ii) * 0x1.0p-53;
|
|
361
|
+
# else
|
|
362
|
+
double out = std::ldexp((int64_t)(gen_bits(rng) >> 10) - two53_ii, -53);
|
|
363
|
+
#endif
|
|
364
|
+
if (unlikely(out == 0)) out = 1;
|
|
365
|
+
return out;
|
|
366
|
+
#else
|
|
367
|
+
uint64_t bits = gen_bits(rng);
|
|
368
|
+
char *rbits_ = reinterpret_cast<char*>(&bits);
|
|
369
|
+
if (is_little_endian) rbits_ += sizeof(uint32_t);
|
|
370
|
+
uint32_t rbits;
|
|
371
|
+
memcpy(&rbits, rbits_, sizeof(uint32_t));
|
|
372
|
+
rbits = rbits & two22_i;
|
|
373
|
+
memcpy(rbits_, &rbits, sizeof(uint32_t));
|
|
374
|
+
# ifdef SUPPORTS_HEXFLOAT
|
|
375
|
+
double out = (double)((int64_t)bits - two53_ii) * 0x1.0p-53;
|
|
376
|
+
# else
|
|
377
|
+
double out = std::ldexp((int64_t)bits - two53_ii, -53);
|
|
378
|
+
#endif
|
|
379
|
+
if (unlikely(out == 0)) out = 1;
|
|
380
|
+
return out;
|
|
381
|
+
#endif
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
/* Normal distribution sampled from uniform numbers using ziggurat method. */
|
|
386
|
+
#include "ziggurat.hpp"
|
|
387
|
+
class StandardNormalDistr
|
|
388
|
+
{
|
|
389
|
+
public:
|
|
390
|
+
StandardNormalDistr() noexcept = default;
|
|
391
|
+
|
|
392
|
+
template <class A, class B>
|
|
393
|
+
StandardNormalDistr(A a, B b) noexcept {}
|
|
394
|
+
|
|
395
|
+
template <class XoshiroRNG>
|
|
396
|
+
#ifndef _FOR_R
|
|
397
|
+
[[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
|
|
398
|
+
#endif
|
|
399
|
+
double operator()(XoshiroRNG &rng) noexcept
|
|
400
|
+
{
|
|
401
|
+
repeat_draw:
|
|
402
|
+
uint64_t rnd = gen_bits(rng);
|
|
403
|
+
uint8_t rectangle = rnd & 255; /* <- number of rectangles (took 8 bits) */
|
|
404
|
+
rnd >>= 8;
|
|
405
|
+
uint8_t sign = rnd & 1; /* <- took 1 bit */
|
|
406
|
+
/* there's currently 56 bits left, already used 1 for the sign, need to
|
|
407
|
+
take 52 for for the uniform draw, so can chop off 3 more than what
|
|
408
|
+
was taken to get there faster. */
|
|
409
|
+
rnd >>= 4;
|
|
410
|
+
double rnorm = rnd * wi_double[rectangle];
|
|
411
|
+
if (likely(rnd < ki_double[rectangle]))
|
|
412
|
+
{
|
|
413
|
+
return sign? rnorm : -rnorm;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
else
|
|
417
|
+
{
|
|
418
|
+
if (likely(rectangle != 0))
|
|
419
|
+
{
|
|
420
|
+
rnd = gen_bits(rng);
|
|
421
|
+
#ifdef SUPPORTS_HEXFLOAT
|
|
422
|
+
double runif = ((double)(rnd >> 12) + 0.5) * 0x1.0p-52;
|
|
423
|
+
#else
|
|
424
|
+
double runif = ((double)(rnd >> 12) + 0.5);
|
|
425
|
+
runif = std::ldexp(runif, -52);
|
|
426
|
+
#endif
|
|
427
|
+
if (runif * (fi_double[rectangle-1] - fi_double[rectangle])
|
|
428
|
+
<
|
|
429
|
+
std::exp(-0.5 * rnorm * rnorm) - fi_double[rectangle])
|
|
430
|
+
{
|
|
431
|
+
return sign? rnorm : -rnorm;
|
|
432
|
+
}
|
|
433
|
+
goto repeat_draw;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
else
|
|
437
|
+
{
|
|
438
|
+
double runif, runif2;
|
|
439
|
+
double a_by_d;
|
|
440
|
+
while (true)
|
|
441
|
+
{
|
|
442
|
+
#ifdef SUPPORTS_HEXFLOAT
|
|
443
|
+
runif = ((double)(gen_bits(rng) >> 12) + 0.5) * 0x1.0p-52;
|
|
444
|
+
runif2 = ((double)(gen_bits(rng) >> 12) + 0.5) * 0x1.0p-52;
|
|
445
|
+
#else
|
|
446
|
+
runif = std::ldexp((double)(gen_bits(rng) >> 12) + 0.5, -52);
|
|
447
|
+
runif2 = std::ldexp((double)(gen_bits(rng) >> 12) + 0.5, -52);
|
|
448
|
+
#endif
|
|
449
|
+
a_by_d = -ziggurat_nor_inv_r * std::log(runif);
|
|
450
|
+
if (-2.0 * std::log(runif2) > a_by_d * a_by_d)
|
|
451
|
+
{
|
|
452
|
+
rnorm = ziggurat_nor_r + a_by_d;
|
|
453
|
+
return sign? rnorm : -rnorm;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
#ifndef _FOR_R
|
|
464
|
+
#if defined(__clang__)
|
|
465
|
+
#pragma clang diagnostic pop
|
|
466
|
+
#endif
|
|
467
|
+
#endif
|