/usr/include/dlib/rand/mersenne_twister.h is in libdlib-dev 18.18-2build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | /* boost random/mersenne_twister.hpp header file
*
* Copyright Jens Maurer 2000-2001
* Distributed under the Boost Software License, Version 1.0. (See
* accompanying file LICENSE_1_0.txt or copy at
* http://www.boost.org/LICENSE_1_0.txt)
*
* See http://www.boost.org for most recent version including documentation.
*
* $Id: mersenne_twister.hpp,v 1.20 2005/07/21 22:04:31 jmaurer Exp $
*
* Revision history
* 2001-02-18 moved to individual header files
*/
#ifndef DLIB_BOOST_RANDOM_MERSENNE_TWISTER_HPP
#define DLIB_BOOST_RANDOM_MERSENNE_TWISTER_HPP
#include <iostream>
#include <algorithm> // std::copy
#include <stdexcept>
#include "../uintn.h"
#include "../serialize.h"
namespace dlib
{
namespace random_helpers
{
// ------------------------------------------------------------------------------------
// http://www.math.keio.ac.jp/matumoto/emt.html
template<
class UIntType,
int w,
int n,
int m,
int r,
UIntType a,
int u,
int s,
UIntType b,
int t,
UIntType c,
int l,
UIntType val
>
class mersenne_twister
{
public:
typedef UIntType result_type;
const static int word_size = w;
const static int state_size = n;
const static int shift_size = m;
const static int mask_bits = r;
const static UIntType parameter_a = a;
const static int output_u = u;
const static int output_s = s;
const static UIntType output_b = b;
const static int output_t = t;
const static UIntType output_c = c;
const static int output_l = l;
const static bool has_fixed_range = false;
mersenne_twister() { seed(); }
explicit mersenne_twister(UIntType value) { seed(value); }
void seed () { seed(UIntType(5489)); }
// compiler-generated copy ctor and assignment operator are fine
void seed(UIntType value)
{
// New seeding algorithm from
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
// In the previous versions, MSBs of the seed affected only MSBs of the
// state x[].
const UIntType mask = ~0u;
x[0] = value & mask;
for (i = 1; i < n; i++) {
// See Knuth "The Art of Computer Programming" Vol. 2, 3rd ed., page 106
x[i] = (1812433253UL * (x[i-1] ^ (x[i-1] >> (w-2))) + i) & mask;
}
}
result_type min() const { return 0; }
result_type max() const
{
// avoid "left shift count >= with of type" warning
result_type res = 0;
for(int i = 0; i < w; ++i)
res |= (1u << i);
return res;
}
result_type operator()();
friend void serialize(
const mersenne_twister& item,
std::ostream& out
)
{
dlib::serialize(item.x, out);
dlib::serialize(item.i, out);
}
friend void deserialize(
mersenne_twister& item,
std::istream& in
)
{
dlib::deserialize(item.x, in);
dlib::deserialize(item.i, in);
}
private:
void twist(int block);
// state representation: next output is o(x(i))
// x[0] ... x[k] x[k+1] ... x[n-1] x[n] ... x[2*n-1] represents
// x(i-k) ... x(i) x(i+1) ... x(i-k+n-1) x(i-k-n) ... x[i(i-k-1)]
// The goal is to always have x(i-n) ... x(i-1) available for
// operator== and save/restore.
UIntType x[2*n];
int i;
};
// ------------------------------------------------------------------------------------
template<
class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val
>
void mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::twist(
int block
)
{
const UIntType upper_mask = (~0u) << r;
const UIntType lower_mask = ~upper_mask;
if(block == 0) {
for(int j = n; j < 2*n; j++) {
UIntType y = (x[j-n] & upper_mask) | (x[j-(n-1)] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
}
} else if (block == 1) {
// split loop to avoid costly modulo operations
{ // extra scope for MSVC brokenness w.r.t. for scope
for(int j = 0; j < n-m; j++) {
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
x[j] = x[j+n+m] ^ (y >> 1) ^ (y&1 ? a : 0);
}
}
for(int j = n-m; j < n-1; j++) {
UIntType y = (x[j+n] & upper_mask) | (x[j+n+1] & lower_mask);
x[j] = x[j-(n-m)] ^ (y >> 1) ^ (y&1 ? a : 0);
}
// last iteration
UIntType y = (x[2*n-1] & upper_mask) | (x[0] & lower_mask);
x[n-1] = x[m-1] ^ (y >> 1) ^ (y&1 ? a : 0);
i = 0;
}
}
// ------------------------------------------------------------------------------------
template<
class UIntType, int w, int n, int m, int r, UIntType a, int u,
int s, UIntType b, int t, UIntType c, int l, UIntType val
>
inline typename mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::result_type
mersenne_twister<UIntType,w,n,m,r,a,u,s,b,t,c,l,val>::operator()(
)
{
if(i == n)
twist(0);
else if(i >= 2*n)
twist(1);
// Step 4
UIntType z = x[i];
++i;
z ^= (z >> u);
z ^= ((z << s) & b);
z ^= ((z << t) & c);
z ^= (z >> l);
return z;
}
// ------------------------------------------------------------------------------------
} // namespace random
typedef random_helpers::mersenne_twister<uint32,32,351,175,19,0xccab8ee7,11,
7,0x31b6ab00,15,0xffe50000,17, 0xa37d3c92> mt11213b;
// validation by experiment from mt19937.c
typedef random_helpers::mersenne_twister<uint32,32,624,397,31,0x9908b0df,11,
7,0x9d2c5680,15,0xefc60000,18, 3346425566U> mt19937;
} // namespace dlib
#endif // DLIB_BOOST_RANDOM_MERSENNE_TWISTER_HPP
|