source: mainline/uspace/lib/cpp/include/impl/random.hpp@ 08e16de0

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 08e16de0 was 08e16de0, checked in by Dzejrou <dzejrou@…>, 7 years ago

cpp: added <random> declarations and some definitions

  • Property mode set to 100644
File size: 11.5 KB
Line 
1/*
2 * Copyright (c) 2018 Jaroslav Jindrak
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef LIBCPP_RANDOM
30#define LIBCPP_RANDOM
31
32#include <cstdlib>
33#include <ctime>
34#include <initializer_list>
35#include <limits>
36#include <type_traits>
37#include <vector>
38
39/**
40 * Note: Variables with one or two lettered
41 * names here are named after their counterparts in
42 * the standard. If one needs to understand their meaning,
43 * they should seek the mentioned standard section near
44 * the declaration of these variables.
45 */
46
47namespace std
48{
49 namespace aux
50 {
51 /**
52 * This is the minimum requirement imposed by the
53 * standard for a type to qualify as a seed sequence
54 * in overloading resolutions.
55 * (This is because the engines have constructors
56 * that accept sequence and seed and without this
57 * minimal requirements overload resolution would fail.)
58 */
59 template<class Sequence, class ResultType>
60 struct is_seed_sequence
61 : aux::value_is<
62 bool, !is_convertible_v<Sequence, ResultType>
63 >
64 { /* DUMMY BODY */ };
65
66 template<class T, class Engine>
67 inline constexpr bool is_seed_sequence_v = is_seed_sequence<T, Engine>::value;
68 }
69
70 /**
71 * 26.5.3.1, class template linear_congruential_engine:
72 */
73
74 template<class UIntType, UIntType a, UIntType c, UIntType m>
75 class linear_congruential_engine
76 {
77 public:
78 using result_type = UIntType;
79
80 static constexpr result_type multiplier = a;
81 static constexpr result_type increment = c;
82 static constexpr result_type modulus = m;
83
84 static constexpr min()
85 {
86 return c == 0U ? 1U : 0U;
87 }
88
89 static constexpr max()
90 {
91 return m - 1U;
92 }
93
94 static constexpr result_type default_seed = 1U;
95
96 explicit linear_congruential_engine(result_type s = default_seed);
97
98 template<class Seq>
99 explicit linear_congruential_engine(
100 enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
101 );
102
103 void seed(result_type s = default_seed);
104
105 template<class Seq>
106 void seed(
107 enable_if_t<aux::is_seed_sequence_v<Seq, result_type>, Seq&> q
108 );
109
110 result_type operator()();
111
112 void discard(unsigned long long z);
113 };
114
115 /**
116 * 26.5.3.2, class template mersenne_twister_engine:
117 */
118
119 template<
120 class UIntType, size_t w, size_t n, size_t m, size_t r,
121 UIntType a, size_t u, UIntType d, size_t s,
122 UIntType b, size_t t, UIntType c, size_t l, UIntType f
123 >
124 class mersenne_twister_engine;
125
126 /**
127 * 26.5.3.3, class template subtract_with_carry_engine:
128 */
129
130 template<class UIntType, size_t w, size_t s, size_t r>
131 class subtract_with_carry_engine;
132
133 /**
134 * 26.5.4.2, class template discard_block_engine:
135 */
136
137 template<class Engine, size_t p, size_t r>
138 class discard_block_engine;
139
140 /**
141 * 26.5.4.3, class template independent_bits_engine:
142 */
143
144 template<class Engine, size_t w, class UIntType>
145 class independent_bits_engine;
146
147 /**
148 * 26.5.4.4, class template shiffle_order_engine:
149 */
150
151 template<class Engine, size_t k>
152 class shuffle_order_engine;
153
154 /**
155 * 26.5.5, engines and engine adaptors with predefined
156 * parameters:
157 * TODO: check their requirements for testing
158 */
159
160 using minstd_rand0 = linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>;
161 using minstd_rand = linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>;
162 using mt19937 = mersenne_twister_engine<
163 uint_fast32_t, 32, 624, 397, 31, 0x9908b0df, 11, 0xffffffff, 7,
164 0x9d2c5680, 15, 0xefc60000, 18, 1812433253
165 >;
166 using mt19937_64 = mersenne_twister_engine<
167 uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9, 29,
168 0x5555555555555555, 17, 0x71d67fffeda60000, 37, 0xfff7eee000000000,
169 43, 6364136223846793005
170 >;
171 using ranlux24_base = subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;
172 using ranlux48_base = subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;
173 using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;
174 using ranlux48 = discard_block_engine<ranlux48_base, 389, 11>;
175 using knuth_b = shuffle_order_engine<minstd_rand0, 256>;
176
177 using default_random_engine = minstd_rand0;
178
179 /**
180 * 26.5.6, class random_device:
181 */
182
183 class random_device
184 {
185 using result_type = unsigned int;
186
187 static constexpr result_type min()
188 {
189 return numeric_limits<result_type>::min();
190 }
191
192 static constexpr result_type max()
193 {
194 return numeric_limits<result_type>::max();
195 }
196
197 explicit random_device(const string& token = "")
198 {
199 /**
200 * Note: token can be used to choose between
201 * random generators, but HelenOS only
202 * has one :/
203 * Also note that it is implementation
204 * defined how this class generates
205 * random numbers and I decided to use
206 * time seeding with C stdlib random,
207 * - feel free to change it if you know
208 * something better.
209 */
210 hel::srandom(hel::time(nullptr));
211 }
212
213 result_type operator()()
214 {
215 return hel::random();
216 }
217
218 double entropy() const noexcept
219 {
220 return 0.0;
221 }
222
223 random_device(const random_device&) = delete;
224 random_device& operator=(const random_device&) = delete;
225 };
226
227 /**
228 * 26.5.7.1, class seed_seq:
229 */
230
231 class seed_seq
232 {
233 public:
234 using result_type = uint_least32_t;
235
236 seed_seq()
237 : vec_{}
238 { /* DUMMY BODY */ }
239
240 template<class T>
241 seed_seq(initializer_list<T> init)
242 : seed_seq(init.begin(), init.end())
243 { /* DUMMY BODY */ }
244
245 template<class InputIterator>
246 seed_seq(InputIterator first, InputIterator last)
247 : vec_{}
248 {
249 while (first != last)
250 vec_.push_back(*first++ % aux::pow2(32));
251 }
252
253 template<class RandomAccessGenerator>
254 void generate(RandomAccessGenerator first,
255 RandomAccessGenerator last)
256 {
257 if (first == last)
258 return;
259
260 // TODO: research this
261 }
262
263 size_t size() const
264 {
265 return vec_.size();
266 }
267
268 template<class OutputIterator>
269 void param(OutputIterator dest) const
270 {
271 for (const auto& x: vec_)
272 *dest++ = x;
273 }
274
275 seed_seq(const seed_seq&) = delete;
276 seed_seq& operator=(const seed_seq&) = delete;
277
278 private:
279 vector<result_type> vec_;
280 };
281
282 /**
283 * 26.5.7.2, function template generate_canonical:
284 */
285
286 template<class RealType, size_t bits, class URNG>
287 RealType generate_canonical(URNG& g);
288
289 /**
290 * 26.5.8.2.1, class template uniform_int_distribution:
291 */
292
293 template<class IntType = int>
294 class uniform_int_distribution;
295
296 /**
297 * 26.5.8.2.2, class template uniform_real_distribution:
298 */
299
300 template<class RealType = double>
301 class uniform_real_distribution;
302
303 /**
304 * 26.5.8.3.1, class bernoulli_distribution:
305 */
306
307 class bernoulli_distribution;
308
309 /**
310 * 26.5.8.3.2, class template binomial_distribution:
311 */
312
313 template<class IntType = int>
314 class binomial_distribution;
315
316 /**
317 * 26.5.8.3.3, class template geometric_distribution:
318 */
319
320 template<class IntType = int>
321 class geometric_distribution;
322
323 /**
324 * 26.5.8.3.4, class template negative_binomial_distribution:
325 */
326
327 template<class IntType = int>
328 class negative_binomial_distribution;
329
330 /**
331 * 26.5.8.4.1, class template poisson_distribution:
332 */
333
334 template<class IntType = int>
335 class poisson_distribution;
336
337 /**
338 * 26.5.8.4.2, class template exponential_distribution:
339 */
340
341 template<class RealType = double>
342 class exponential_distribution;
343
344 /**
345 * 26.5.8.4.3, class template gamma_distribution:
346 */
347
348 template<class RealType = double>
349 class gamma_distribution;
350
351 /**
352 * 26.5.8.4.4, class template weibull_distribution:
353 */
354
355 template<class RealType = double>
356 class weibull_distribution;
357
358 /**
359 * 26.5.8.4.5, class template extreme_value_distribution:
360 */
361
362 template<class RealType = double>
363 class extreme_value_distribution;
364
365 /**
366 * 26.5.8.5.1, class template normal_distribution:
367 */
368
369 template<class RealType = double>
370 class normal_distribution;
371
372 /**
373 * 26.5.8.5.2, class template lognormal_distribution:
374 */
375
376 template<class RealType = double>
377 class lognormal_distribution;
378
379 /**
380 * 26.5.8.5.3, class template chi_squared_distribution:
381 */
382
383 template<class RealType = double>
384 class chi_squared_distribution;
385
386 /**
387 * 26.5.8.5.4, class template cauchy_distribution:
388 */
389
390 template<class RealType = double>
391 class cauchy_distribution;
392
393 /**
394 * 26.5.8.5.5, class template fisher_f_distribution:
395 */
396
397 template<class RealType = double>
398 class fisher_f_distribution;
399
400 /**
401 * 26.5.8.5.6, class template student_t_distribution:
402 */
403
404 template<class RealType = double>
405 class student_t_distribution;
406
407 /**
408 * 26.5.8.6.1, class template discrete_distribution:
409 */
410
411 template<class IntType = int>
412 class discrete_distribution;
413
414 /**
415 * 26.5.8.6.2, class template piecewise_constant_distribution:
416 */
417
418 template<class RealType = double>
419 class piecewise_constant_distribution;
420
421 /**
422 * 26.5.8.6.3, class template piecewise_linear_distribution:
423 */
424
425 template<class RealType = double>
426 class piecewise_linear_distribution;
427}
428
429#endif
Note: See TracBrowser for help on using the repository browser.