Scippy

SoPlex

Sequential object-oriented simPlex

random.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file random.h
17  * @brief Random numbers.
18  */
19 #ifndef _RANDOM_H_
20 #define _RANDOM_H_
21 
22 #include <assert.h>
23 #include <stdint.h>
24 #include <algorithm>
25 
26 namespace soplex
27 {
28 
29 /* initial seeds for KISS random number generator */
30 #define DEFAULT_LIN UINT32_C(123456789)
31 #define DEFAULT_XOR UINT32_C(362436000)
32 #define DEFAULT_MWC UINT32_C(521288629)
33 #define DEFAULT_CST UINT32_C(7654321)
34 
35 /* defines for linear congruential generator */
36 #define RSTEP UINT64_C(1103515245)
37 #define RADD UINT64_C(12345)
38 
39 /**@brief Random numbers.
40  @ingroup Elementary
41 
42  Class Random provides random Real variables, i.e. a value variable that
43  gives another value each time it is accessed. It may be used just like an
44  ordinary Real by means of an overloaded cast operator Real()%.
45 
46  This is an implementation of KISS random number generator developed by George Marsaglia.
47  KISS is combination of three different random number generators:
48  - Linear congruential generator
49  - Xorshift
50  - Lag-1 Multiply-with-carry
51 
52  KISS has a period of 2^123 and passes all statistical test part of BigCrush-Test of TestU01 [1].
53 
54  [1] http://dl.acm.org/citation.cfm?doid=1268776.1268777
55 */
56 class Random
57 {
58 private:
59 
60  //--------------------------------------
61  /**@name Data */
62  ///@{
63  uint32_t seedshift; ///< initial shift for random seeds.
64  uint32_t lin_seed; ///< random seed for linear congruential RNS.
65  uint32_t xor_seed; ///< random seed for XOR-shift RNS.
66  uint32_t mwc_seed; ///< random seed Multiple-with-carry RNS.
67  uint32_t cst_seed; ///< random seed shifted for mwc_seed.
68  ///@}
69 
70  //--------------------------------------
71  /**@name Helpers */
72  ///@{
73  /// executes KISS random number generator and returns a pseudo random Real value in [0,1].
75  {
76  uint64_t t;
77 
78  /* linear congruential */
79  lin_seed = (uint32_t)(lin_seed * RSTEP + RADD);
80 
81  /* Xorshift */
82  xor_seed ^= (xor_seed << 13);
83  xor_seed ^= (xor_seed >> 17);
84  xor_seed ^= (xor_seed << 5);
85 
86  /* Multiply-with-carry */
87  t = UINT64_C(698769069) * mwc_seed + cst_seed;
88  cst_seed = (uint32_t)(t >> 32);
89  mwc_seed = (uint32_t) t;
90 
91  return (lin_seed + xor_seed + mwc_seed) / (Real)UINT32_MAX;
92  }
93 
94  ///@}
95 
96 public:
97 
98  //--------------------------------------
99  /**@name Access */
100  ///@{
101  /// returns next random number.
102  Real next(Real minimum = 0.0, Real maximum = 1.0)
103  {
104  Real randnumber = next_random();
105 
106  /* we multiply minimum and maximum separately by randnumber in order to avoid overflow if they are more than
107  * std::numeric_limits<Real>::max() apart
108  */
109  return minimum * (1.0 - randnumber) + maximum * randnumber;
110  }
111 
112  /// returns the initial seed shift
113  uint32_t getSeed() const
114  {
115  return seedshift;
116  }
117 
118  ///@}
119 
120  //--------------------------------------
121  /**@name Modification */
122  ///@{
123  /// initialize all seeds of the random number generator.
124  void setSeed(uint32_t initshift)
125  {
126  seedshift = initshift;
127 
128  /* use std::max to avoid zero after over flowing */
129  lin_seed = std::max(DEFAULT_LIN + initshift, 1u);
130  xor_seed = std::max(DEFAULT_XOR + initshift, 1u);
131  mwc_seed = std::max(DEFAULT_MWC + initshift, 1u);
132  cst_seed = DEFAULT_CST + initshift;
133 
134  assert(lin_seed > 0);
135  assert(xor_seed > 0);
136  assert(mwc_seed > 0);
137 
138  /* advance state once to have more random values */
139  (void) next_random();
140  }
141 
142  ///@}
143 
144 
145  //--------------------------------------
146  /**@name Constructors / destructors */
147  ///@{
148  /// default constructor.
149  /** Constructs a new (pseudo) Random variable using \p randomseed as seed for the random
150  variable's sequence.
151  */
152  explicit
153  Random(uint32_t randomseed = 0)
154  {
155  setSeed(randomseed);
156  }
157 
158  /// destructor
160  {}
161  ///@}
162 };
163 
164 } // namespace soplex
165 #endif // _RANDOM_H_
Random numbers.Class Random provides random Real variables, i.e. a value variable that gives another ...
Definition: random.h:56
#define DEFAULT_LIN
Definition: random.h:30
#define RSTEP
Definition: random.h:36
#define DEFAULT_XOR
Definition: random.h:31
uint32_t seedshift
initial shift for random seeds.
Definition: random.h:63
double Real
Definition: spxdefines.h:256
#define DEFAULT_MWC
Definition: random.h:32
Real next(Real minimum=0.0, Real maximum=1.0)
returns next random number.
Definition: random.h:102
Random(uint32_t randomseed=0)
default constructor.
Definition: random.h:153
uint32_t cst_seed
random seed shifted for mwc_seed.
Definition: random.h:67
Real next_random()
executes KISS random number generator and returns a pseudo random Real value in [0,1].
Definition: random.h:74
Everything should be within this namespace.
uint32_t getSeed() const
returns the initial seed shift
Definition: random.h:113
void setSeed(uint32_t initshift)
initialize all seeds of the random number generator.
Definition: random.h:124
uint32_t lin_seed
random seed for linear congruential RNS.
Definition: random.h:64
#define RADD
Definition: random.h:37
uint32_t xor_seed
random seed for XOR-shift RNS.
Definition: random.h:65
#define DEFAULT_CST
Definition: random.h:33
uint32_t mwc_seed
random seed Multiple-with-carry RNS.
Definition: random.h:66
~Random()
destructor
Definition: random.h:159