Library of Assembled Shared Sources
random.cpp
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2022 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45#include "lass_common.h"
46#include "random.h"
47
48#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
49# pragma warning(disable: 4996) // 'deprecated-declaration': deprecation-message (or "was declared deprecated")
50#else
51# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
52#endif
53
54namespace lass
55{
56namespace num
57{
58
59// --- RandomParkMiller ----------------------------------------------------------------------------
60
61/** default constructor.
62 * will seed with default value
63 */
68
69
70
71/** default constructor.
72 * will seed with default value
73 */
75{
76 this->seed(seed);
77}
78
79
80
81void RandomParkMiller::seed(result_type seed)
82{
83 buffer_ = seed ^ seedMask_;
84}
85
86
87
88/** draw a random number
89 */
91{
92 result_type k = buffer_ / schrageQuotient_;
93 buffer_ = multiplier_ * (buffer_ - k * schrageQuotient_) - k * schrageRest_;
94 return buffer_;
95}
96
97
98
99// --- RandomMT19937 -------------------------------------------------------------------------------
100
101/** default constructor.
102 * will seed with default value on first use.
103 */
105 index_(stateSize_ + 1)
106{
107}
108
109
110
111/** construct with seed.
112 */
117
118
119
120/** initializes with a seed.
121 */
123{
124 LASS_META_ASSERT(sizeof(result_type) * lass::bitsPerByte == 32, if_TValue_is_32_bits_then_the_wordMasks_are_not_necessary);
125
126 state_[0] = seed; // & wordMask_;
127 for (TValue i = 1; i < stateSize_; ++i)
128 {
129 state_[i] = (1812433253 * (state_[i - 1] ^ (state_[i - 1] >> 30)) + i);
130 //state_[i] &= wordMask_;
131 }
132 index_ = stateSize_;
133}
134
135
136
137/** draw a random number
138 */
140{
141 if (index_ >= stateSize_)
142 {
143 reload();
144 }
145
146 result_type y = state_[index_++];
147
148 // Tempering
149 //
150 y ^= (y >> 11);
151 y ^= (y << 7) & 0x9d2c5680;
152 y ^= (y << 15) & 0xefc60000;
153 y ^= (y >> 18);
154
155 return y;
156}
157
158
159// private
160
161/** generate N words at a time
162 */
163void RandomMT19937::reload()
164{
165
166 // if seed() has not been called, a default initial seed is used.
167 //
168 if (index_ == stateSize_ + 1)
169 {
170 seed(5489);
171 }
172
173 size_t k = 0;
174 for (; k < stateSize_ - shiftSize_; ++k)
175 {
176 state_[k] = twist(state_[k], state_[k + 1], state_[k + shiftSize_]);
177 }
178 for (; k < stateSize_ - 1; ++k)
179 {
180 state_[k] = twist(state_[k], state_[k + 1], state_[k + shiftSize_ - stateSize_]);
181 }
182 state_[stateSize_ - 1] = twist(state_[stateSize_ - 1], state_[0], state_[shiftSize_ - 1]);
183 index_ = 0;
184}
185
186
187inline RandomMT19937::result_type RandomMT19937::twist(result_type a, result_type b, result_type c) const
188{
189 static const result_type magic01[2] = { 0x0, 0x9908b0df }; // magic01[x] = x * magic_ for x = 0, 1
190
191 const result_type y = (a & 0x80000000) | (b & 0x7fffffff);
192 return c ^ (y >> 1) ^ magic01[y & 0x1];
193}
194
195
196
197// --- RandomXorShift128Plus -----------------------------------------------------------------------
198
199RandomXorShift128Plus::RandomXorShift128Plus()
200{
201}
202
203RandomXorShift128Plus::RandomXorShift128Plus(result_type seed)
204{
205 this->seed(seed);
206}
207
208RandomXorShift128Plus::TValue RandomXorShift128Plus::operator()()
209{
210 TValue x = state_[0];
211 const TValue y = state_[1];
212 state_[0] = y;
213 x ^= x << 23; // a
214 state_[1] = x ^ y ^ (x >> 17) ^ (y >> 26); // b, c
215 return state_[1] + y;
216}
217
218void RandomXorShift128Plus::seed(result_type seed)
219{
220 state_[0] = seed;
221 state_[1] = 0xffff;
222}
223
224
225
226// --- RandomHalton --------------------------------------------------------------------------------
227
228RandomRadicalInverse::RandomRadicalInverse(size_t base) :
229 index_(0),
230 base_(base),
231 invBase_(1. / static_cast<TValue>(base))
232{
233}
234
235RandomRadicalInverse::TValue RandomRadicalInverse::operator()()
236{
237 TValue result = 0;
238 TValue f = 1;
239 size_t n = ++index_;
240 while (n)
241 {
242 const size_t r = n % base_;
243 n /= base_;
244 f *= invBase_;
245 result += static_cast<TValue>(r) * f;
246 }
247 return result;
248}
249
250void RandomRadicalInverse::seed(size_t index)
251{
252 index_ = index;
253}
254
255
256
257// --- RandomXKCD ---------------------------------------------------------------------------------
258
259RandomXKCD::result_type RandomXKCD::operator()()
260{
261 return 4;
262}
263
264}
265
266}
267
268// EOF
num::Tuint32 TValue
type of return value.
Definition random.h:163
void seed(result_type seed)
initializes with a seed.
Definition random.cpp:122
result_type operator()()
draw a random number
Definition random.cpp:139
num::Tuint32 result_type
type of return value.
Definition random.h:162
RandomMT19937()
default constructor.
Definition random.cpp:104
num::Tuint32 TValue
type of return value.
Definition random.h:105
result_type operator()()
draw a random number
Definition random.cpp:90
num::Tuint32 result_type
type of return value.
Definition random.h:104
RandomParkMiller()
default constructor.
Definition random.cpp:64
double TValue
type of return value.
Definition random.h:254
int result_type
type of return value.
Definition random.h:280
num::Tuint64 TValue
type of return value.
Definition random.h:223
#define LASS_META_ASSERT(expression, message)
complite time static check
numeric types and traits.
Definition basic_ops.h:70
Library for Assembled Shared Sources.
Definition config.h:53