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.
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