1 /*********************                                                        */
2 /*! \file random.cpp
3  ** \verbatim
4  ** Top contributors (to current version):
5  **   Aina Niemetz
6  ** This file is part of the CVC4 project.
7  ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
8  ** in the top-level source directory) and their institutional affiliations.
9  ** All rights reserved.  See the file COPYING in the top-level source
10  ** directory for licensing information.\endverbatim
11  **
12  ** \brief A Random Number Generator.
13  **
14  ** A random number generator, implements the xorshift* generator
15  ** (see S. Vigna, An experimental exploration of Marsaglia's xorshift
16  ** generators, scrambled. ACM Trans. Math. Softw. 42(4): 30:1-30:23, 2016).
17  **/
18 
19 #include "util/random.h"
20 
21 #include <cfloat>
22 #include "base/cvc4_assert.h"
23 
24 namespace CVC4 {
25 
Random(uint64_t seed)26 Random::Random(uint64_t seed) { setSeed(seed); }
27 
setSeed(uint64_t seed)28 void Random::setSeed(uint64_t seed)
29 {
30   d_seed = seed == 0 ? ~seed : seed;
31   d_state = d_seed;
32 }
33 
operator ()()34 uint64_t Random::operator()() { return rand(); }
35 
rand()36 uint64_t Random::rand()
37 {
38   /* xorshift* generator (see S. Vigna, An experimental exploration of
39    * Marsaglia's xorshift generators, scrambled. ACM Trans. Math. Softw.
40    * 42(4): 30:1-30:23, 2016). */
41   d_state ^= d_state >> 12;
42   d_state ^= d_state << 25;
43   d_state ^= d_state >> 27;
44   return d_state * uint64_t{2685821657736338717};
45 }
46 
pick(uint64_t from,uint64_t to)47 uint64_t Random::pick(uint64_t from, uint64_t to)
48 {
49   Assert(from <= to);
50   Assert(to < UINT64_MAX);
51   return (Random::rand() % (to - from + 1)) + from;
52 }
53 
pickDouble(double from,double to)54 double Random::pickDouble(double from, double to)
55 {
56   Assert(from <= to);
57   Assert(to <= DBL_MAX);
58   return Random::rand() * (to - from) + from;
59 }
60 
pickWithProb(double probability)61 bool Random::pickWithProb(double probability)
62 {
63   Assert(probability <= 1);
64   uint64_t p = (uint64_t) (probability * 1000);
65   uint64_t r = pick(0, 999);
66   return r < p;
67 }
68 
69 }
70