View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.rng.simple;
18  
19  import org.apache.commons.rng.UniformRandomProvider;
20  import org.apache.commons.rng.RestorableUniformRandomProvider;
21  import org.apache.commons.rng.simple.internal.ProviderBuilder;
22  import org.apache.commons.rng.simple.internal.SeedFactory;
23  
24  /**
25   * This class provides the API for creating generators of random numbers.
26   *
27   * <p>Usage examples:</p>
28   * <pre><code>
29   *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT);
30   * </code></pre>
31   * or
32   * <pre><code>
33   *  final int[] seed = new int[] { 196, 9, 0, 226 };
34   *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed);
35   * </code></pre>
36   * or
37   * <pre><code>
38   *  final int[] seed = RandomSource.createIntArray(256);
39   *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed);
40   * </code></pre>
41   * where the first argument to method {@code create} is the identifier
42   * of the generator's concrete implementation, and the second the is the
43   * (optional) seed.
44   *
45   * <p>
46   * In the first form, a random seed will be {@link SeedFactory generated
47   * automatically}; in the second form, a fixed seed is used; a random seed
48   * is explicitly generated in the third form.
49   * </p>
50   *
51   * <p>
52   * Seeding is the procedure by which a value (or set of values) is
53   * used to <i>initialize</i> a generator instance.
54   * The requirement that a given seed will always result in the same
55   * internal state allows to create different instances of a generator
56   * that will produce the same sequence of pseudo-random numbers.
57   * </p>
58   *
59   * <p>
60   * The type of data used as a seed depends on the concrete implementation
61   * as some types may not provide enough information to fully initialize
62   * the generator's internal state.
63   * <br>
64   * The reference algorithm's seeding procedure (if provided) operates
65   * on a value of a (single) <i>native</i> type:
66   * Each concrete implementation's constructor creates an instance using
67   * the native type whose information contents is used to set the
68   * internal state.
69   * <br>
70   * When the seed value passed by the caller is of the native type, it is
71   * expected that the sequences produced will be identical to those
72   * produced by other implementations of the same reference algorithm.
73   * <br>
74   * However, when the seed value passed by the caller is not of the native
75   * type, a transformation is performed by this library and the resulting
76   * native type value will <i>not</i> contain more information than the
77   * original seed value.
78   * If the algorithm's native type is "simpler" than the type passed by
79   * the caller, then some (unused) information will even be lost.
80   * <br>
81   * The transformation from non-native to native seed type is arbitrary,
82   * as long as it does not reduce the amount of information required by
83   * the algorithm to initialize its state.
84   * The consequence of the transformation is that sequences produced
85   * by this library may <i>not</i> be the same as the sequences produced
86   * by other implementations of the same algorithm!
87   * </p>
88   *
89   * <p>
90   * For each algorithm, the Javadoc mentions the "ideal" size of the seed,
91   * meaning the number of {@code int} or {@code long} values that is neither
92   * too large (i.e. some of the seed is useless) or too small (i.e. an
93   * internal procedure will fill the state with redundant information
94   * computed from the given seed).
95   * </p>
96   *
97   * <p>
98   * Note that some algorithms are inherently sensitive to having too low
99   * diversity in their initial state.
100  * For example, it is often a bad idea to use a seed that is mostly
101  * composed of zeroes, or of repeated values.
102  * </p>
103  *
104  * <p>
105  * This class provides methods to generate random seeds (single values
106  * or arrays of values, of {@code int} or {@code long} types) that can
107  * be passed to the {@link RandomSource#create(RandomSource,Object,Object[])
108  * generators factory method}.
109  * </p>
110  * <p>
111  * Although the seed-generating methods defined in this class will likely
112  * return different values each time they are called, there is no guarantee:
113  * </p>
114  * <ul>
115  *  <li>
116  *   In any sub-sequence, it is <a href="https://en.wikipedia.org/wiki/Birthday_problem">
117  *   expected</a> that the same numbers can occur, with a probability getting
118  *   higher as the range of allowed values is smaller and the sequence becomes
119  *   longer.
120  *  </li>
121  *  <li>
122  *   It possible that the resulting "seed" will not be <i>good</i> (i.e.
123  *   it will not generate a sufficiently uniformly random sequence for the
124  *   intended purpose), even if the generator is good!
125  *   The only way to ensure that the selected seed will make the generator
126  *   produce a good sequence is to submit that sequence to a series of
127  *   stringent tests, as provided by tools such as
128  *   <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php">dieharder</a>
129  *   or <a href="http://simul.iro.umontreal.ca/testu01/tu01.html">TestU01</a>.
130  *  </li>
131  * </ul>
132  *
133  * <p>
134  * The current implementations have no provision for producing non-overlapping
135  * sequences.
136  * For parallel applications, a possible workaround is that each thread uses
137  * a generator of a different type (see {@link #TWO_CMRES_SELECT}).
138  * </p>
139  *
140  * <p>
141  * <b>Note:</b>
142  * Seeding is not equivalent to restoring the internal state of an
143  * <i>already initialized</i> generator.
144  * Indeed, generators can have a state that is more complex than the
145  * seed, and seeding is thus a transformation (from seed to state).
146  * Implementations do not provide the inverse transformation (from
147  * state to seed), hence it is not generally possible to know the seed
148  * that would initialize a new generator instance to the current state
149  * of another instance.
150  * Reseeding is also inefficient if the purpose is to continue the
151  * same sequence where another instance left off, as it would require
152  * to "replay" all the calls performed by that other instance (and it
153  * would require to know the number of calls to the primary source of
154  * randomness, which is also not usually accessible).
155  * </p>
156  *
157  * @since 1.0
158  */
159 public enum RandomSource {
160     /**
161      * Source of randomness is {@link org.apache.commons.rng.core.source32.JDKRandom}.
162      * <ul>
163      *  <li>Native seed type: {@code Long}.</li>
164      *  <li>Native seed size: 1.</li>
165      * </ul>
166      */
167     JDK(ProviderBuilder.RandomSourceInternal.JDK),
168     /**
169      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well512a}.
170      * <ul>
171      *  <li>Native seed type: {@code int[]}.</li>
172      *  <li>Native seed size: 16.</li>
173      * </ul>
174      */
175     WELL_512_A(ProviderBuilder.RandomSourceInternal.WELL_512_A),
176     /**
177      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well1024a}.
178      * <ul>
179      *  <li>Native seed type: {@code int[]}.</li>
180      *  <li>Native seed size: 32.</li>
181      * </ul>
182      */
183     WELL_1024_A(ProviderBuilder.RandomSourceInternal.WELL_1024_A),
184     /**
185      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937a}.
186      * <ul>
187      *  <li>Native seed type: {@code int[]}.</li>
188      *  <li>Native seed size: 624.</li>
189      * </ul>
190      */
191     WELL_19937_A(ProviderBuilder.RandomSourceInternal.WELL_19937_A),
192     /**
193      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937c}.
194      * <ul>
195      *  <li>Native seed type: {@code int[]}.</li>
196      *  <li>Native seed size: 624.</li>
197      * </ul>
198      */
199     WELL_19937_C(ProviderBuilder.RandomSourceInternal.WELL_19937_C),
200     /**
201      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497a}.
202      * <ul>
203      *  <li>Native seed type: {@code int[]}.</li>
204      *  <li>Native seed size: 1391.</li>
205      * </ul>
206      */
207     WELL_44497_A(ProviderBuilder.RandomSourceInternal.WELL_44497_A),
208     /**
209      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497b}.
210      * <ul>
211      *  <li>Native seed type: {@code int[]}.</li>
212      *  <li>Native seed size: 1391.</li>
213      * </ul>
214      */
215     WELL_44497_B(ProviderBuilder.RandomSourceInternal.WELL_44497_B),
216     /**
217      * Source of randomness is {@link org.apache.commons.rng.core.source32.MersenneTwister}.
218      * <ul>
219      *  <li>Native seed type: {@code int[]}.</li>
220      *  <li>Native seed size: 624.</li>
221      * </ul>
222      */
223     MT(ProviderBuilder.RandomSourceInternal.MT),
224     /**
225      * Source of randomness is {@link org.apache.commons.rng.core.source32.ISAACRandom}.
226      * <ul>
227      *  <li>Native seed type: {@code int[]}.</li>
228      *  <li>Native seed size: 256.</li>
229      * </ul>
230      */
231     ISAAC(ProviderBuilder.RandomSourceInternal.ISAAC),
232     /**
233      * Source of randomness is {@link org.apache.commons.rng.core.source64.SplitMix64}.
234      * <ul>
235      *  <li>Native seed type: {@code Long}.</li>
236      *  <li>Native seed size: 1.</li>
237      * </ul>
238      */
239     SPLIT_MIX_64(ProviderBuilder.RandomSourceInternal.SPLIT_MIX_64),
240     /**
241      * Source of randomness is {@link org.apache.commons.rng.core.source64.XorShift1024Star}.
242      * <ul>
243      *  <li>Native seed type: {@code long[]}.</li>
244      *  <li>Native seed size: 16.</li>
245      * </ul>
246      */
247     XOR_SHIFT_1024_S(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S),
248     /**
249      * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres}.
250      * This generator is equivalent to {@link #TWO_CMRES_SELECT} with the choice of the
251      * pair {@code (0, 1)} for the two subcycle generators.
252      * <ul>
253      *  <li>Native seed type: {@code Integer}.</li>
254      *  <li>Native seed size: 1.</li>
255      * </ul>
256      */
257     TWO_CMRES(ProviderBuilder.RandomSourceInternal.TWO_CMRES),
258     /**
259      * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres},
260      * with explicit selection of the two subcycle generators.
261      * The selection of the subcycle generator is by passing its index in the internal
262      * table, a value between 0 (included) and 13 (included).
263      * The two indices must be different.
264      * Different choices of an ordered pair of indices create independent generators.
265      * <ul>
266      *  <li>Native seed type: {@code Integer}.</li>
267      *  <li>Native seed size: 1.</li>
268      * </ul>
269      */
270     TWO_CMRES_SELECT(ProviderBuilder.RandomSourceInternal.TWO_CMRES_SELECT),
271     /**
272      * Source of randomness is {@link org.apache.commons.rng.core.source64.MersenneTwister64}.
273      * <ul>
274      *  <li>Native seed type: {@code long[]}.</li>
275      *  <li>Native seed size: 312.</li>
276      * </ul>
277      */
278     MT_64(ProviderBuilder.RandomSourceInternal.MT_64),
279     /**
280      * Source of randomness is {@link org.apache.commons.rng.core.source32.MultiplyWithCarry256}.
281      * <ul>
282      *  <li>Native seed type: {@code int[]}.</li>
283      *  <li>Native seed size: 257.</li>
284      * </ul>
285      */
286     MWC_256(ProviderBuilder.RandomSourceInternal.MWC_256),
287     /**
288      * Source of randomness is {@link org.apache.commons.rng.core.source32.KISSRandom}.
289      * <ul>
290      *  <li>Native seed type: {@code int[]}.</li>
291      *  <li>Native seed size: 4.</li>
292      * </ul>
293      */
294     KISS(ProviderBuilder.RandomSourceInternal.KISS);
295 
296     /** Internal identifier. */
297     private final ProviderBuilder.RandomSourceInternal internalIdentifier;
298 
299     /**
300      * @param id Internal identifier.
301      */
302     RandomSource(ProviderBuilder.RandomSourceInternal id) {
303         internalIdentifier = id;
304     }
305 
306     /**
307      * @return the internal identifier.
308      */
309     ProviderBuilder.RandomSourceInternal getInternalIdentifier() {
310         return internalIdentifier;
311     }
312 
313     /**
314      * Checks whether the type of given {@code seed} is the native type
315      * of the implementation.
316      *
317      * @param seed Seed value.
318      * @return {@code true} if the type of {@code seed} is the native
319      * type for this RNG source.
320      */
321     public boolean isNativeSeed(Object seed) {
322         return internalIdentifier.isNativeSeed(seed);
323     }
324 
325     /**
326      * Creates a random number generator with a random seed.
327      *
328      * <p>Usage example:</p>
329      * <pre><code>
330      *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT);
331      * </code></pre>
332      * <p>or, if a {@link RestorableUniformRandomProvider "save/restore"} functionality is needed,</p>
333      * <pre><code>
334      *  RestorableUniformRandomProvider rng = RandomSource.create(RandomSource.MT);
335      * </code></pre>
336      *
337      * @param source RNG type.
338      * @return the RNG.
339      *
340      * @see #create(RandomSource,Object,Object[])
341      */
342     public static RestorableUniformRandomProvider create(RandomSource source) {
343         return create(source, null);
344     }
345 
346     /**
347      * Creates a random number generator with the given {@code seed}.
348      *
349      * <p>Usage example:</p>
350      * <pre><code>
351      *  UniformRandomProvider rng = RandomSource.create(RandomSource.TWO_CMRES_SELECT, 26219, 6, 9);
352      * </code></pre>
353      *
354      * <p>Valid types for the {@code seed} are:</p>
355      *  <ul>
356      *   <li>{@code Integer} (or {@code int})</li>
357      *   <li>{@code Long} (or {@code long})</li>
358      *   <li>{@code int[]}</li>
359      *   <li>{@code long[]}</li>
360      *   <li>{@code byte[]}</li>
361      *  </ul>
362      *
363      * <p>Notes:</p>
364      * <ul>
365      *  <li>
366      *   When the seed type passed as argument is more complex (i.e. more
367      *   bits can be independently chosen) than the generator's
368      *   {@link #isNativeSeed(Object) native type}, the conversion of a
369      *   set of different seeds will necessarily result in the same value
370      *   of the native seed type.
371      *  </li>
372      *  <li>
373      *   When the native seed type is an array, the same remark applies
374      *   when the array contains more bits than the state of the generator.
375      *  </li>
376      *  <li>
377      *   When the native seed type is an array and the {@code seed} is
378      *   {@code null}, the size of the generated array will be 128.
379      *  </li>
380      * </ul>
381      *
382      * @param source RNG type.
383      * @param seed Seed value.  It can be {@code null} (in which case a
384      * random value will be used).
385      * @param data Additional arguments to the implementation's constructor.
386      * Please refer to the documentation of each specific implementation.
387      * @return the RNG.
388      * @throws UnsupportedOperationException if the type of the {@code seed}
389      * is invalid.
390      * @throws IllegalStateException if data is missing to initialize the
391      * generator implemented by the given {@code source}.
392      *
393      * @see #create(RandomSource)
394      */
395     public static RestorableUniformRandomProvider create(RandomSource source,
396                                                          Object seed,
397                                                          Object ... data) {
398         return ProviderBuilder.create(source.getInternalIdentifier(), seed, data);
399     }
400 
401     /**
402      * Creates a number for use as a seed.
403      *
404      * @return a random number.
405      */
406     public static int createInt() {
407         return SeedFactory.createInt();
408     }
409 
410     /**
411      * Creates a number for use as a seed.
412      *
413      * @return a random number.
414      */
415     public static long createLong() {
416         return SeedFactory.createLong();
417     }
418 
419     /**
420      * Creates an array of numbers for use as a seed.
421      *
422      * @param n Size of the array to create.
423      * @return an array of {@code n} random numbers.
424      */
425     public static int[] createIntArray(int n) {
426         return SeedFactory.createIntArray(n);
427     }
428 
429     /**
430      * Creates an array of numbers for use as a seed.
431      *
432      * @param n Size of the array to create.
433      * @return an array of {@code n} random numbers.
434      */
435     public static long[] createLongArray(int n) {
436         return SeedFactory.createLongArray(n);
437     }
438 
439     /**
440      * Wraps the given {@code delegate} generator in a new instance that
441      * does not allow access to the "save/restore" functionality.
442      *
443      * @param delegate Generator to which calls will be delegated.
444      * @return a new instance whose state cannot be saved or restored.
445      */
446     public static UniformRandomProvider unrestorable(final UniformRandomProvider delegate) {
447         return new UniformRandomProvider() {
448             /** {@inheritDoc} */
449             @Override
450             public void nextBytes(byte[] bytes) {
451                 delegate.nextBytes(bytes);
452             }
453 
454             /** {@inheritDoc} */
455             @Override
456             public void nextBytes(byte[] bytes,
457                                   int start,
458                                   int len) {
459                 delegate.nextBytes(bytes, start, len);
460             }
461 
462             /** {@inheritDoc} */
463             @Override
464             public int nextInt() {
465                 return delegate.nextInt();
466             }
467 
468             /** {@inheritDoc} */
469             @Override
470             public int nextInt(int n) {
471                 return delegate.nextInt(n);
472             }
473 
474             /** {@inheritDoc} */
475             @Override
476             public long nextLong() {
477                 return delegate.nextLong();
478             }
479 
480             /** {@inheritDoc} */
481             @Override
482             public long nextLong(long n) {
483                 return delegate.nextLong(n);
484             }
485 
486             /** {@inheritDoc} */
487             @Override
488             public boolean nextBoolean() {
489                 return delegate.nextBoolean();
490             }
491 
492             /** {@inheritDoc} */
493             @Override
494             public float nextFloat() {
495                 return delegate.nextFloat();
496             }
497 
498             /** {@inheritDoc} */
499             @Override
500             public double nextDouble() {
501                 return delegate.nextDouble();
502             }
503 
504             /** {@inheritDoc} */
505             @Override
506             public String toString() {
507                 return delegate.toString();
508             }
509         };
510     }
511 }