1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.jstats.streams;
11
12 /***
13 * The DX-120-4 pseudo random number generator. This generator is described in
14 * <a href="http://www.cs.memphis.edu/~dengl/dx-rng/dengxu2002.pdf"> A System of
15 * High-dimensional, Efficient, Long-cycle and Portable Uniform Random Number
16 * Generators </a>.
17 * <p>
18 * (c) copyright 2004 <a href="http://www.simulation.tudelft.nl">Delft
19 * University of Technology </a>, the Netherlands. <br>
20 * See for project information <a href="http://www.simulation.tudelft.nl">
21 * www.simulation.tudelft.nl </a> <br>
22 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
23 * License (GPL) </a>, no warranty <br>
24 *
25 * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
26 * Jacobs </a>
27 * @version 1.2 2004-03-18
28 * @since 1.0
29 */
30 public class DX120Generator extends RandomNumberGenerator
31 {
32 /*** the k value of the DX-120 Generator */
33 private static final int K = 120;
34
35 /*** the mask value 2^31-1 (or 1 < < 31)-1 */
36 private static final int MASK = Integer.MAX_VALUE;
37
38 /*** the LCG multiplier */
39 private static final int MULTIPLIER = 16807;
40
41 /*** the buffer for this generator */
42 private int[] buffer = null;
43
44 /*** indexing attributes */
45 private int index;
46
47 /*** indexing attributes */
48 private int k13;
49
50 /*** indexing attributes */
51 private int k23;
52
53 /***
54 * constructs a new LC48Generator. the seed value used equals
55 * System.currentTimeMillis()
56 */
57 public DX120Generator()
58 {
59 this(System.currentTimeMillis());
60 }
61
62 /***
63 * constructs a new LC48Generator
64 *
65 * @param seed the seed
66 */
67 public DX120Generator(final long seed)
68 {
69 super(seed);
70 this.initialize();
71 }
72
73 /***
74 * initializes the generator
75 */
76 private void initialize()
77 {
78 this.buffer = new int[DX120Generator.K];
79 this.buffer[0] = ((int) super.seed) & MASK;
80 if (this.buffer[0] == 0)
81 {
82
83
84 this.setSeed(System.currentTimeMillis());
85 }
86 if (this.buffer[0] < 0)
87 {
88 this.buffer[0] = Math.abs(this.buffer[0] - 1);
89 }
90 for (int i = 1; i < K; i++)
91 {
92 this.buffer[i] = (MULTIPLIER * this.buffer[i - 1]) & MASK;
93 }
94 this.index = K - 1;
95 this.k13 = K - K / 3 - 1;
96 this.k23 = K - 2 * K / 3 - 1;
97 }
98
99 /***
100 * @see nl.tudelft.simulation.jstats.streams.RandomNumberGenerator#next(int)
101 */
102 protected synchronized long next(final int bits)
103 {
104 if (bits < 0 || bits > 64)
105 {
106 throw new IllegalArgumentException("bits (" + bits
107 + ") not in range [0,64]");
108 }
109 int tempIndex = this.index;
110 if (++this.index >= K)
111 {
112 this.index = 0;
113 }
114 if (++this.k13 >= K)
115 {
116 this.k13 = 0;
117 }
118 if (++this.k23 >= K)
119 {
120 this.k23 = 0;
121 }
122 this.buffer[this.index] = (521673 * (this.buffer[this.index]
123 + this.buffer[this.k13] + this.buffer[this.k23] + this.buffer[tempIndex]))
124 & MASK;
125 if (bits <= 32)
126 {
127 return (this.buffer[this.index]) >>> (32 - bits);
128 }
129 return (this.buffer[this.index]) << 32 + this.next(bits - 32);
130 }
131
132 /***
133 * @see nl.tudelft.simulation.jstats.streams.StreamInterface#setSeed(long)
134 */
135 public synchronized void setSeed(final long seed)
136 {
137 this.seed = seed;
138 this.initialize();
139 }
140 }