File: MTRand.h

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (106 lines) | stat: -rw-r--r-- 2,663 bytes parent folder | download | duplicates (7)
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
#ifndef KAIK_MTRAND_HDR
#define KAIK_MTRAND_HDR

// Mersenne Twister random number generator
class MTRand_int32 {
	public:
		// default constructor: uses default seed only if this is the first instance
		MTRand_int32() {
			if (!init) {
				seed(5489UL);
				init = true;
			}
		}
		// constructor with 32 bit int as seed
		MTRand_int32(unsigned int s) {
			seed(s); init = true;
		}
		virtual ~MTRand_int32() {
		}

		// seed with 32 bit integer
		void seed(unsigned int);

		// overload operator() to make this a generator (functor)
		unsigned int operator () () {
			return rand_int32();
		}

	// used by derived classes, otherwise not accessible; use the ()-operator
	protected:
		// generate 32 bit random integer
		unsigned int rand_int32();

	// private functions used to generate the pseudo random numbers
	private:
		// compile time constants
		static const int n = 624, m = 397;

		// state vector array
		static unsigned int state[n];
		// position in state array
		static int p;
		// true if init function is called
		static bool init;

		// used by gen_state()
		unsigned int twiddle(unsigned int, unsigned int) const;
		// generate new state
		void gen_state();

		// make copy constructor and assignment operator unavailable, they don't make sense

		// copy constructor not defined
		MTRand_int32(const MTRand_int32&);
		// assignment operator not defined
		void operator = (const MTRand_int32&);
};


// inline for speed, must therefore reside in header file
inline unsigned int MTRand_int32::twiddle(unsigned int u, unsigned int v) const {
	return (((u & 0x80000000UL) | (v & 0x7FFFFFFFUL)) >> 1) ^ ((v & 1UL)? 0x9908B0DFUL: 0x0UL);
}

// generate 32 bit random int
inline unsigned int MTRand_int32::rand_int32() {
	if (p == n) {
		// new state vector needed
		gen_state();
	}

	// gen_state() is split off to be non-inline, because it is only called once
	// in every 624 calls and otherwise irand() would become too big to get inlined
 	unsigned int x = state[p++];
	x ^= (x >> 11);
	x ^= (x << 7) & 0x9D2C5680UL;
	x ^= (x << 15) & 0xEFC60000UL;

	return (x ^ (x >> 18));
}

// generates double floating point numbers in the half-open interval [0, 1)
class MTRand: public MTRand_int32 {
	public:
		MTRand(): MTRand_int32() {
		}
		// The day 64 bit evil computers take over change this back to long
		MTRand(unsigned int seed): MTRand_int32(seed) {
		}
		~MTRand() {
		}

		double operator () () {
			// divided by 2^32
			return static_cast<float>(rand_int32()) * (1. / 4294967296.);
		}

	private:
		// copy constructor not defined
		MTRand(const MTRand&);
		// assignment operator not defined
		void operator = (const MTRand&);
};


#endif