isotree 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/LICENSE.txt +2 -2
  4. data/README.md +32 -14
  5. data/ext/isotree/ext.cpp +144 -31
  6. data/ext/isotree/extconf.rb +7 -7
  7. data/lib/isotree/isolation_forest.rb +110 -30
  8. data/lib/isotree/version.rb +1 -1
  9. data/vendor/isotree/LICENSE +1 -1
  10. data/vendor/isotree/README.md +165 -27
  11. data/vendor/isotree/include/isotree.hpp +2111 -0
  12. data/vendor/isotree/include/isotree_oop.hpp +394 -0
  13. data/vendor/isotree/inst/COPYRIGHTS +62 -0
  14. data/vendor/isotree/src/RcppExports.cpp +525 -52
  15. data/vendor/isotree/src/Rwrapper.cpp +1931 -268
  16. data/vendor/isotree/src/c_interface.cpp +953 -0
  17. data/vendor/isotree/src/crit.hpp +4232 -0
  18. data/vendor/isotree/src/dist.hpp +1886 -0
  19. data/vendor/isotree/src/exp_depth_table.hpp +134 -0
  20. data/vendor/isotree/src/extended.hpp +1444 -0
  21. data/vendor/isotree/src/external_facing_generic.hpp +399 -0
  22. data/vendor/isotree/src/fit_model.hpp +2401 -0
  23. data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
  24. data/vendor/isotree/src/helpers_iforest.hpp +813 -0
  25. data/vendor/isotree/src/{impute.cpp → impute.hpp} +353 -122
  26. data/vendor/isotree/src/indexer.cpp +515 -0
  27. data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
  28. data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
  29. data/vendor/isotree/src/isoforest.hpp +1659 -0
  30. data/vendor/isotree/src/isotree.hpp +1804 -392
  31. data/vendor/isotree/src/isotree_exportable.hpp +99 -0
  32. data/vendor/isotree/src/merge_models.cpp +159 -16
  33. data/vendor/isotree/src/mult.hpp +1321 -0
  34. data/vendor/isotree/src/oop_interface.cpp +842 -0
  35. data/vendor/isotree/src/oop_interface.hpp +278 -0
  36. data/vendor/isotree/src/other_helpers.hpp +219 -0
  37. data/vendor/isotree/src/predict.hpp +1932 -0
  38. data/vendor/isotree/src/python_helpers.hpp +134 -0
  39. data/vendor/isotree/src/ref_indexer.hpp +154 -0
  40. data/vendor/isotree/src/robinmap/LICENSE +21 -0
  41. data/vendor/isotree/src/robinmap/README.md +483 -0
  42. data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
  43. data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1620 -0
  44. data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
  45. data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
  46. data/vendor/isotree/src/serialize.cpp +4300 -139
  47. data/vendor/isotree/src/sql.cpp +141 -59
  48. data/vendor/isotree/src/subset_models.cpp +174 -0
  49. data/vendor/isotree/src/utils.hpp +3808 -0
  50. data/vendor/isotree/src/xoshiro.hpp +467 -0
  51. data/vendor/isotree/src/ziggurat.hpp +405 -0
  52. metadata +38 -104
  53. data/vendor/cereal/LICENSE +0 -24
  54. data/vendor/cereal/README.md +0 -85
  55. data/vendor/cereal/include/cereal/access.hpp +0 -351
  56. data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
  57. data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
  58. data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
  59. data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
  60. data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
  61. data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
  62. data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
  63. data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
  64. data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
  65. data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
  66. data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
  67. data/vendor/cereal/include/cereal/details/util.hpp +0 -84
  68. data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
  69. data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
  70. data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
  71. data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
  72. data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
  73. data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
  74. data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
  75. data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
  76. data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
  77. data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
  78. data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
  79. data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
  80. data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
  81. data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
  82. data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
  83. data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
  84. data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
  85. data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
  86. data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
  87. data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
  88. data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
  89. data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
  90. data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
  91. data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
  92. data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
  93. data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
  94. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
  95. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
  96. data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
  97. data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
  98. data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
  99. data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
  100. data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
  101. data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
  102. data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
  103. data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
  104. data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
  105. data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
  106. data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
  107. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
  108. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
  109. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
  110. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
  111. data/vendor/cereal/include/cereal/macros.hpp +0 -154
  112. data/vendor/cereal/include/cereal/specialize.hpp +0 -139
  113. data/vendor/cereal/include/cereal/types/array.hpp +0 -79
  114. data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
  115. data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
  116. data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
  117. data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
  118. data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
  119. data/vendor/cereal/include/cereal/types/common.hpp +0 -129
  120. data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
  121. data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
  122. data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
  123. data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
  124. data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
  125. data/vendor/cereal/include/cereal/types/list.hpp +0 -62
  126. data/vendor/cereal/include/cereal/types/map.hpp +0 -36
  127. data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
  128. data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
  129. data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
  130. data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
  131. data/vendor/cereal/include/cereal/types/set.hpp +0 -103
  132. data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
  133. data/vendor/cereal/include/cereal/types/string.hpp +0 -61
  134. data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
  135. data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
  136. data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
  137. data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
  138. data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
  139. data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
  140. data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
  141. data/vendor/cereal/include/cereal/version.hpp +0 -52
  142. data/vendor/isotree/src/Makevars +0 -4
  143. data/vendor/isotree/src/crit.cpp +0 -912
  144. data/vendor/isotree/src/dist.cpp +0 -749
  145. data/vendor/isotree/src/extended.cpp +0 -790
  146. data/vendor/isotree/src/fit_model.cpp +0 -1090
  147. data/vendor/isotree/src/helpers_iforest.cpp +0 -324
  148. data/vendor/isotree/src/isoforest.cpp +0 -771
  149. data/vendor/isotree/src/mult.cpp +0 -607
  150. data/vendor/isotree/src/predict.cpp +0 -853
  151. 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