wfmath 1.0.3
A math library for the Worldforge system.
MersenneTwister.h
1// MersenneTwister.h
2//
3// The WorldForge Project
4// Copyright (C) 2013 The WorldForge Project
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License along
17// with this program; if not, write to the Free Software Foundation, Inc.,
18// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19//
20// For information about WorldForge and its authors, please contact
21// the Worldforge Web Site at http://www.worldforge.org.
22//
23#ifndef WFMATH_MERSENNE_TWISTER_H_
24#define WFMATH_MERSENNE_TWISTER_H_
25
26#include <iosfwd>
27#include <climits>
28#include <cmath>
29#include <cstdint>
30
31namespace WFMath {
32
33class MTRand {
34public:
35 typedef uint32_t uint32;
36
37 static const uint32 state_size = 624;
38
39public:
40 MTRand();
41 explicit MTRand(uint32 oneSeed);
42 explicit MTRand(const uint32 bigSeed[], uint32 seedLength = state_size);
43
44 // real-valued random numbers on [0, 1] or [0, n]
45 template<typename FloatT>
46 FloatT rand();
47 double rand();
48 double rand(const double& n);
49
50 // integer-valued random numbers on [0, 2^32-1] or [0, n]
51 uint32 randInt();
52 uint32 randInt(uint32 n);
53
54 void seed();
55 void seed(uint32 oneSeed);
56 void seed(const uint32 init_vector[], uint32 init_vector_length = state_size);
57
58 std::ostream& save(std::ostream&) const;
59 std::istream& load(std::istream&);
60
61 static MTRand instance;
62
63private:
64 uint32 state[state_size];
65 uint32 index;
66};
67
68
69inline MTRand::MTRand(uint32 oneSeed)
70: index(0)
71{ seed(oneSeed); }
72
73inline MTRand::MTRand(const uint32 bigSeed[], const uint32 seedLength)
74: index(0)
75{ seed(bigSeed, seedLength); }
76
77inline MTRand::MTRand()
78: index(0)
79{ seed(); }
80
81template<>
82inline float MTRand::rand<float>()
83{ return float(randInt()) * (1.0f/4294967295.0f); }
84
85template<>
86inline double MTRand::rand<double>()
87{ return double(randInt()) * (1.0/4294967295.0); }
88
89inline double MTRand::rand()
90{ return double(randInt()) * (1.0/4294967295.0); }
91
92inline double MTRand::rand( const double& n )
93{ return rand() * n; }
94
95
96inline MTRand::uint32 MTRand::randInt(uint32 n)
97{
98 uint32 used = n;
99 used |= used >> 1u;
100 used |= used >> 2u;
101 used |= used >> 4u;
102 used |= used >> 8u;
103 used |= used >> 16u;
104
105 uint32 i;
106 do
107 i = randInt() & used;
108 while( i > n );
109 return i;
110}
111
112
113#if 0
114inline void MTRand::save(uint32* saveArray) const
115{
116 uint32 *sa = saveArray;
117 const uint32 *s = state;
118 int i = state_size;
119 for( ; i--; *sa++ = *s++ ) {}
120 *sa = left;
121}
122
123
124inline void MTRand::load(uint32 *const loadArray)
125{
126 uint32 *s = state;
127 uint32 *la = loadArray;
128 int i = state_size;
129 for( ; i--; *s++ = *la++ ) {}
130 left = *la;
131 pNext = &state[state_size-left];
132}
133#endif
134
135std::ostream& operator<<(std::ostream& os, MTRand const& mtrand);
136std::istream& operator>>(std::istream& is, MTRand& mtrand);
137
138} // namespace
139
140#endif // WFMATH_MERSENNE_TWISTER_H_
Generic library namespace.
Definition: shape.h:41