1
2
3
4
5
6
7
8
9
10 package nl.tudelft.simulation.jstats.streams;
11
12 /***
13 * The RandomNumberGenerator class provides an abstract for all pseudo random
14 * number generators.
15 * <p>
16 * (c) copyright 2004 <a href="http://www.simulation.tudelft.nl">Delft
17 * University of Technology </a>, the Netherlands. <br>
18 * See for project information <a href="http://www.simulation.tudelft.nl">
19 * www.simulation.tudelft.nl </a> <br>
20 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
21 * License (GPL) </a>, no warranty <br>
22 *
23 * @author <a href="http://www.simulation.tudelft.nl/people/jacobs.html">Peter
24 * Jacobs </a>
25 * @version 1.6 2004-03-18
26 * @since 1.0
27 */
28 public abstract class RandomNumberGenerator implements StreamInterface
29 {
30 /*** the seed of the generator */
31 protected long seed = -1;
32
33 /***
34 * constructs a new RandomNumberGenerator. The seed value used in the rng is
35 * set to System.currentTimeMillis();
36 */
37 public RandomNumberGenerator()
38 {
39 this(System.currentTimeMillis());
40 }
41
42 /***
43 * constructs a new RandomNumberGenerator.
44 *
45 * @param seed the seed of the generator.
46 */
47 public RandomNumberGenerator(final long seed)
48 {
49 super();
50 if (seed <= 0)
51 {
52 throw new IllegalArgumentException("seed(" + seed + ")<=0");
53 }
54 this.setSeed(seed);
55 }
56
57 /***
58 * @see nl.tudelft.simulation.jstats.streams.StreamInterface#reset()
59 */
60 public void reset()
61 {
62 this.setSeed(this.seed);
63 }
64
65 /***
66 * returns the next value in the stream.
67 *
68 * @param bits the number of bits used
69 * @return the next value.
70 */
71 protected abstract long next(final int bits);
72
73 /***
74 * Returns the next pseudorandom, uniformly distributed <code>boolean</code>
75 * value from this random number generator's sequence. The general contract
76 * of <tt>nextBoolean</tt> is that one <tt>boolean</tt> value is
77 * pseudorandomly generated and returned. The values <code>true</code> and
78 * <code>false</code> are produced with (approximately) equal probability.
79 * The method <tt>nextBoolean</tt> is implemented by class <tt>Random</tt>
80 * as follows: <blockquote>
81 *
82 * <pre>
83 * public boolean nextBoolean()
84 * {
85 * return next(1) != 0;
86 * }
87 * </pre>
88 *
89 * </blockquote>
90 *
91 * @return the next pseudorandom, uniformly distributed <code>boolean</code>
92 * value from this random number generator's sequence.
93 * @since 1.2
94 */
95 public boolean nextBoolean()
96 {
97 return next(1) != 0;
98 }
99
100 /***
101 * Returns the next pseudorandom, uniformly distributed <code>double</code>
102 * value between <code>0.0</code> and <code>1.0</code> from this random
103 * number generator's sequence.
104 * <p>
105 * The general contract of <tt>nextDouble</tt> is that one <tt>double</tt>
106 * value, chosen (approximately) uniformly from the range <tt>0.0d</tt>
107 * (inclusive) to <tt>1.0d</tt> (exclusive), is pseudorandomly generated
108 * and returned. All 2 <font size="-1"> <sup>64 </sup> </font> possible
109 * <tt>float</tt> values of the form <i>m x </i>2 <font
110 * size="-1"> <sup>-64 </sup> </font>, where <i>m </i> is a positive integer
111 * less than 2 <font size="-1"> <sup>64 </sup> </font>, are produced with
112 * (approximately) equal probability.
113 *
114 * @return the next pseudorandom, uniformly distributed <code>double</code>
115 * value between <code>0.0</code> and <code>1.0</code> from this
116 * random number generator's sequence.
117 */
118 public double nextDouble()
119 {
120 long l = ((next(26)) << 27) + next(27);
121 return l / (double) (1L << 53);
122 }
123
124 /***
125 * Returns the next pseudorandom, uniformly distributed <code>float</code>
126 * value between <code>0.0</code> and <code>1.0</code> from this random
127 * number generator's sequence.
128 * <p>
129 * The general contract of <tt>nextFloat</tt> is that one <tt>float</tt>
130 * value, chosen (approximately) uniformly from the range <tt>0.0f</tt>
131 * (inclusive) to <tt>1.0f</tt> (exclusive), is pseudorandomly generated
132 * and returned. All 2 <font size="-1"> <sup>24 </sup> </font> possible
133 * <tt>float</tt> values of the form <i>m x  </i>2 <font
134 * size="-1"> <sup>-24 </sup> </font>, where <i>m </i> is a positive integer
135 * less than 2 <font size="-1"> <sup>24 </sup> </font>, are produced with
136 * (approximately) equal probability. The method <tt>nextFloat</tt> is
137 * implemented by class <tt>Random</tt> as follows: <blockquote>
138 *
139 * <pre>
140 *
141 *
142 * public float nextFloat() {
143 * return next(24) / ((float)(1 < < 24));
144 * }
145 *
146 * </pre>
147 *
148 * </blockquote> The hedge "approximately" is used in the foregoing
149 * description only because the next method is only approximately an
150 * unbiased source of independently chosen bits. If it were a perfect source
151 * or randomly chosen bits, then the algorithm shown would choose
152 * <tt>float</tt> values from the stated range with perfect uniformity.
153 * <p>
154 *
155 * @return the next pseudorandom, uniformly distributed <code>float</code>
156 * value between <code>0.0</code> and <code>1.0</code> from this
157 * random number generator's sequence.
158 */
159 public float nextFloat()
160 {
161 int i = (int) this.next(24);
162 return i / ((float) (1 << 24));
163 }
164
165 /***
166 * Returns the next pseudorandom, uniformly distributed <code>int</code>
167 * value from this random number generator's sequence. The general contract
168 * of <tt>nextInt</tt> is that one <tt>int</tt> value is pseudorandomly
169 * generated and returned. All 2 <font size="-1"> <sup>32 </sup> </font>
170 * possible <tt>int</tt> values are produced with (approximately) equal
171 * probability. The method <tt>nextInt</tt> is implemented by class
172 * <tt>Random</tt> as follows: <blockquote>
173 *
174 * <pre>
175 * public int nextInt()
176 * {
177 * return next(32);
178 * }
179 * </pre>
180 *
181 * </blockquote>
182 *
183 * @return the next pseudorandom, uniformly distributed <code>int</code>
184 * value from this random number generator's sequence.
185 */
186 public int nextInt()
187 {
188 return (int) this.next(32);
189 }
190
191 /***
192 * Returns a pseudorandom, uniformly distributed <tt>int</tt> value
193 * between i (inclusive) and j, drawn from this random number generator's
194 * sequence. The general contract of <tt>nextInt</tt> is that one
195 * <tt>int</tt> value in the specified range is pseudorandomly generated
196 * and returned. All <tt>n</tt> possible <tt>int</tt> values are
197 * produced with (approximately) equal probability.
198 *
199 * @param i the lower value
200 * @param j the higher value
201 * @return the result
202 */
203 public synchronized int nextInt(final int i, final int j)
204 {
205 if (i < 0 || j <= 0 || i >= j)
206 {
207 throw new IllegalArgumentException("i, j must be positive");
208 }
209 int n = j - i;
210 if ((n & -n) == n)
211 {
212 return (int) (i + (n * next(31)) >> 31);
213 }
214 int bits, val;
215 do
216 {
217 bits = (int) this.next(31);
218 val = bits % n;
219 } while (bits - val + (n - 1) < 0);
220 return i + val;
221 }
222
223 /***
224 * Returns the next pseudorandom, uniformly distributed <code>long</code>
225 * value from this random number generator's sequence. The general contract
226 * of <tt>nextLong</tt> is that one long value is pseudorandomly generated
227 * and returned. All 2 <font size="-1"> <sup>64 </sup> </font> possible
228 * <tt>long</tt> values are produced with (approximately) equal
229 * probability. The method <tt>nextLong</tt> is implemented by class
230 * <tt>Random</tt> as follows: <blockquote>
231 *
232 * <pre>
233 *
234 *
235 * public long nextLong() {
236 * return ((long)next(32) < < 32) + next(32);
237 * }
238 *
239 * </pre>
240 *
241 * </blockquote>
242 *
243 * @return the next pseudorandom, uniformly distributed <code>long</code>
244 * value from this random number generator's sequence.
245 */
246 public long nextLong()
247 {
248 return ((next(32)) << 32) + next(32);
249 }
250
251 /***
252 * @see nl.tudelft.simulation.jstats.streams.StreamInterface#setSeed(long)
253 */
254 public abstract void setSeed(final long seed);
255
256 /***
257 * @see nl.tudelft.simulation.jstats.streams.StreamInterface#getSeed()
258 */
259 public long getSeed()
260 {
261 return this.seed;
262 }
263
264 /***
265 * @see java.lang.Object#toString()
266 */
267 public String toString()
268 {
269 return this.getClass().toString() + "[" + this.seed + "]";
270 }
271 }