View Javadoc

1   /*
2    * @(#) RandomNumberGenerator.java Feb 19, 2004
3    * 
4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
5    * the Netherlands All rights reserved.
6    * 
7    * This software is proprietary information of Delft University of Technology
8    * The code is published under the General Public License
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&nbsp;x&nbsp; </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&nbsp;x&nbsp </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 &lt; &lt; 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) // i.e., n is a power of 2
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) &lt; &lt; 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 }