isotree 0.2.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -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 +2116 -0
  12. data/vendor/isotree/include/isotree_oop.hpp +394 -0
  13. data/vendor/isotree/inst/COPYRIGHTS +132 -0
  14. data/vendor/isotree/src/RcppExports.cpp +594 -57
  15. data/vendor/isotree/src/Rwrapper.cpp +2452 -304
  16. data/vendor/isotree/src/c_interface.cpp +958 -0
  17. data/vendor/isotree/src/crit.hpp +4236 -0
  18. data/vendor/isotree/src/digamma.hpp +184 -0
  19. data/vendor/isotree/src/dist.hpp +1886 -0
  20. data/vendor/isotree/src/exp_depth_table.hpp +134 -0
  21. data/vendor/isotree/src/extended.hpp +1444 -0
  22. data/vendor/isotree/src/external_facing_generic.hpp +399 -0
  23. data/vendor/isotree/src/fit_model.hpp +2401 -0
  24. data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
  25. data/vendor/isotree/src/helpers_iforest.hpp +814 -0
  26. data/vendor/isotree/src/{impute.cpp → impute.hpp} +382 -123
  27. data/vendor/isotree/src/indexer.cpp +515 -0
  28. data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
  29. data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
  30. data/vendor/isotree/src/isoforest.hpp +1659 -0
  31. data/vendor/isotree/src/isotree.hpp +1815 -394
  32. data/vendor/isotree/src/isotree_exportable.hpp +99 -0
  33. data/vendor/isotree/src/merge_models.cpp +159 -16
  34. data/vendor/isotree/src/mult.hpp +1321 -0
  35. data/vendor/isotree/src/oop_interface.cpp +844 -0
  36. data/vendor/isotree/src/oop_interface.hpp +278 -0
  37. data/vendor/isotree/src/other_helpers.hpp +219 -0
  38. data/vendor/isotree/src/predict.hpp +1932 -0
  39. data/vendor/isotree/src/python_helpers.hpp +114 -0
  40. data/vendor/isotree/src/ref_indexer.hpp +154 -0
  41. data/vendor/isotree/src/robinmap/LICENSE +21 -0
  42. data/vendor/isotree/src/robinmap/README.md +483 -0
  43. data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
  44. data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1639 -0
  45. data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
  46. data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
  47. data/vendor/isotree/src/serialize.cpp +4316 -139
  48. data/vendor/isotree/src/sql.cpp +143 -61
  49. data/vendor/isotree/src/subset_models.cpp +174 -0
  50. data/vendor/isotree/src/utils.hpp +3786 -0
  51. data/vendor/isotree/src/xoshiro.hpp +463 -0
  52. data/vendor/isotree/src/ziggurat.hpp +405 -0
  53. metadata +40 -105
  54. data/vendor/cereal/LICENSE +0 -24
  55. data/vendor/cereal/README.md +0 -85
  56. data/vendor/cereal/include/cereal/access.hpp +0 -351
  57. data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
  58. data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
  59. data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
  60. data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
  61. data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
  62. data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
  63. data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
  64. data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
  65. data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
  66. data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
  67. data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
  68. data/vendor/cereal/include/cereal/details/util.hpp +0 -84
  69. data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
  70. data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
  71. data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
  72. data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
  73. data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
  74. data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
  75. data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
  76. data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
  77. data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
  78. data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
  79. data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
  80. data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
  81. data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
  82. data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
  83. data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
  84. data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
  85. data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
  86. data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
  87. data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
  88. data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
  89. data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
  90. data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
  91. data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
  92. data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
  93. data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
  94. data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
  95. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
  96. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
  97. data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
  98. data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
  99. data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
  100. data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
  101. data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
  102. data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
  103. data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
  104. data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
  105. data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
  106. data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
  107. data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
  108. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
  109. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
  110. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
  111. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
  112. data/vendor/cereal/include/cereal/macros.hpp +0 -154
  113. data/vendor/cereal/include/cereal/specialize.hpp +0 -139
  114. data/vendor/cereal/include/cereal/types/array.hpp +0 -79
  115. data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
  116. data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
  117. data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
  118. data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
  119. data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
  120. data/vendor/cereal/include/cereal/types/common.hpp +0 -129
  121. data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
  122. data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
  123. data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
  124. data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
  125. data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
  126. data/vendor/cereal/include/cereal/types/list.hpp +0 -62
  127. data/vendor/cereal/include/cereal/types/map.hpp +0 -36
  128. data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
  129. data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
  130. data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
  131. data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
  132. data/vendor/cereal/include/cereal/types/set.hpp +0 -103
  133. data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
  134. data/vendor/cereal/include/cereal/types/string.hpp +0 -61
  135. data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
  136. data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
  137. data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
  138. data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
  139. data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
  140. data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
  141. data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
  142. data/vendor/cereal/include/cereal/version.hpp +0 -52
  143. data/vendor/isotree/src/Makevars +0 -4
  144. data/vendor/isotree/src/crit.cpp +0 -912
  145. data/vendor/isotree/src/dist.cpp +0 -749
  146. data/vendor/isotree/src/extended.cpp +0 -790
  147. data/vendor/isotree/src/fit_model.cpp +0 -1090
  148. data/vendor/isotree/src/helpers_iforest.cpp +0 -324
  149. data/vendor/isotree/src/isoforest.cpp +0 -771
  150. data/vendor/isotree/src/mult.cpp +0 -607
  151. data/vendor/isotree/src/predict.cpp +0 -853
  152. data/vendor/isotree/src/utils.cpp +0 -1566
@@ -0,0 +1,463 @@
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 produce a non-uniform
289
+ distribution as they divide by the maximum value of the generator
290
+ (not all numbers between zero and one are representable).
291
+ Hence this replacement. It is not too much slower
292
+ than what the compiler's header use. */
293
+ class UniformUnitInterval
294
+ {
295
+ public:
296
+ UniformUnitInterval() noexcept = default;
297
+
298
+ template <class A, class B>
299
+ UniformUnitInterval(A a, B b) noexcept {}
300
+
301
+ template <class XoshiroRNG>
302
+ #ifndef _FOR_R
303
+ [[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
304
+ #endif
305
+ double operator()(XoshiroRNG &rng) noexcept
306
+ {
307
+ #if SIZE_MAX >= UINT64_MAX
308
+ # ifdef SUPPORTS_HEXFLOAT
309
+ return (double)(gen_bits(rng) >> 11) * 0x1.0p-53;
310
+ # else
311
+ return std::ldexp(gen_bits(rng) >> 11, -53);
312
+ # endif
313
+ #else
314
+ uint64_t bits = gen_bits(rng);
315
+ char *rbits_ = reinterpret_cast<char*>(&bits);
316
+ if (is_little_endian) rbits_ += sizeof(uint32_t);
317
+ uint32_t rbits;
318
+ memcpy(&rbits, rbits_, sizeof(uint32_t));
319
+ rbits = rbits & two21_i;
320
+ memcpy(rbits_, &rbits, sizeof(uint32_t));
321
+ # ifdef SUPPORTS_HEXFLOAT
322
+ return (double)bits * 0x1.0p-53;
323
+ # else
324
+ return std::ldexp(bits, -53);
325
+ #endif
326
+ #endif
327
+ }
328
+ };
329
+
330
+ /* Note: this should sample in an open interval [-1,1].
331
+ It's however quite hard to sample uniformly in an open
332
+ interval with floating point numbers, since it'd require
333
+ drawing a random number up to a power of 2 plus one, which
334
+ does not translate into the required precision with
335
+ increments of 2^n that IEEE754 floats have around the unit
336
+ interval. Nevertheless, since it'd be less than ideal to
337
+ output zero from here (that is, it would mean not taking
338
+ a column when creating a random hyperplane), it instead
339
+ will transform exact zeros into exact ones. */
340
+ class UniformMinusOneToOne
341
+ {
342
+ public:
343
+ UniformMinusOneToOne() noexcept = default;
344
+
345
+ template <class A, class B>
346
+ UniformMinusOneToOne(A a, B b) noexcept {}
347
+
348
+ template <class XoshiroRNG>
349
+ #ifndef _FOR_R
350
+ [[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
351
+ #endif
352
+ double operator()(XoshiroRNG &rng) noexcept
353
+ {
354
+ #if SIZE_MAX >= UINT64_MAX
355
+ # ifdef SUPPORTS_HEXFLOAT
356
+ double out = (double)((int64_t)(gen_bits(rng) >> 10) - two53_ii) * 0x1.0p-53;
357
+ # else
358
+ double out = std::ldexp((int64_t)(gen_bits(rng) >> 10) - two53_ii, -53);
359
+ #endif
360
+ if (unlikely(out == 0)) out = 1;
361
+ return out;
362
+ #else
363
+ uint64_t bits = gen_bits(rng);
364
+ char *rbits_ = reinterpret_cast<char*>(&bits);
365
+ if (is_little_endian) rbits_ += sizeof(uint32_t);
366
+ uint32_t rbits;
367
+ memcpy(&rbits, rbits_, sizeof(uint32_t));
368
+ rbits = rbits & two22_i;
369
+ memcpy(rbits_, &rbits, sizeof(uint32_t));
370
+ # ifdef SUPPORTS_HEXFLOAT
371
+ double out = (double)((int64_t)bits - two53_ii) * 0x1.0p-53;
372
+ # else
373
+ double out = std::ldexp((int64_t)bits - two53_ii, -53);
374
+ #endif
375
+ if (unlikely(out == 0)) out = 1;
376
+ return out;
377
+ #endif
378
+ }
379
+ };
380
+
381
+ /* Normal distribution sampled from uniform numbers using ziggurat method. */
382
+ #include "ziggurat.hpp"
383
+ class StandardNormalDistr
384
+ {
385
+ public:
386
+ StandardNormalDistr() noexcept = default;
387
+
388
+ template <class A, class B>
389
+ StandardNormalDistr(A a, B b) noexcept {}
390
+
391
+ template <class XoshiroRNG>
392
+ #ifndef _FOR_R
393
+ [[gnu::optimize("no-trapping-math"), gnu::optimize("no-math-errno")]]
394
+ #endif
395
+ double operator()(XoshiroRNG &rng) noexcept
396
+ {
397
+ repeat_draw:
398
+ uint64_t rnd = gen_bits(rng);
399
+ uint8_t rectangle = rnd & 255; /* <- number of rectangles (took 8 bits) */
400
+ rnd >>= 8;
401
+ uint8_t sign = rnd & 1; /* <- took 1 bit */
402
+ /* there's currently 56 bits left, already used 1 for the sign, need to
403
+ take 52 for for the uniform draw, so can chop off 3 more than what
404
+ was taken to get there faster. */
405
+ rnd >>= 4;
406
+ double rnorm = rnd * wi_double[rectangle];
407
+ if (likely(rnd < ki_double[rectangle]))
408
+ {
409
+ return sign? rnorm : -rnorm;
410
+ }
411
+
412
+ else
413
+ {
414
+ if (likely(rectangle != 0))
415
+ {
416
+ rnd = gen_bits(rng);
417
+ #ifdef SUPPORTS_HEXFLOAT
418
+ double runif = ((double)(rnd >> 12) + 0.5) * 0x1.0p-52;
419
+ #else
420
+ double runif = ((double)(rnd >> 12) + 0.5);
421
+ runif = std::ldexp(runif, -52);
422
+ #endif
423
+ if (runif * (fi_double[rectangle-1] - fi_double[rectangle])
424
+ <
425
+ std::exp(-0.5 * rnorm * rnorm) - fi_double[rectangle])
426
+ {
427
+ return sign? rnorm : -rnorm;
428
+ }
429
+ goto repeat_draw;
430
+ }
431
+
432
+ else
433
+ {
434
+ double runif, runif2;
435
+ double a_by_d;
436
+ while (true)
437
+ {
438
+ #ifdef SUPPORTS_HEXFLOAT
439
+ runif = ((double)(gen_bits(rng) >> 12) + 0.5) * 0x1.0p-52;
440
+ runif2 = ((double)(gen_bits(rng) >> 12) + 0.5) * 0x1.0p-52;
441
+ #else
442
+ runif = std::ldexp((double)(gen_bits(rng) >> 12) + 0.5, -52);
443
+ runif2 = std::ldexp((double)(gen_bits(rng) >> 12) + 0.5, -52);
444
+ #endif
445
+ a_by_d = -ziggurat_nor_inv_r * std::log(runif);
446
+ if (-2.0 * std::log(runif2) > a_by_d * a_by_d)
447
+ {
448
+ rnorm = ziggurat_nor_r + a_by_d;
449
+ return sign? rnorm : -rnorm;
450
+ }
451
+ }
452
+ }
453
+ }
454
+ }
455
+ };
456
+
457
+ }
458
+
459
+ #ifndef _FOR_R
460
+ #if defined(__clang__)
461
+ #pragma clang diagnostic pop
462
+ #endif
463
+ #endif