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      * </ul>
165      */
166     JDK(ProviderBuilder.RandomSourceInternal.JDK),
167     /**
168      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well512a}.
169      * <ul>
170      *  <li>Native seed type: {@code int[]}.</li>
171      *  <li>Native seed size: 16.</li>
172      * </ul>
173      */
174     WELL_512_A(ProviderBuilder.RandomSourceInternal.WELL_512_A),
175     /**
176      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well1024a}.
177      * <ul>
178      *  <li>Native seed type: {@code int[]}.</li>
179      *  <li>Native seed size: 32.</li>
180      * </ul>
181      */
182     WELL_1024_A(ProviderBuilder.RandomSourceInternal.WELL_1024_A),
183     /**
184      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937a}.
185      * <ul>
186      *  <li>Native seed type: {@code int[]}.</li>
187      *  <li>Native seed size: 624.</li>
188      * </ul>
189      */
190     WELL_19937_A(ProviderBuilder.RandomSourceInternal.WELL_19937_A),
191     /**
192      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well19937c}.
193      * <ul>
194      *  <li>Native seed type: {@code int[]}.</li>
195      *  <li>Native seed size: 624.</li>
196      * </ul>
197      */
198     WELL_19937_C(ProviderBuilder.RandomSourceInternal.WELL_19937_C),
199     /**
200      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497a}.
201      * <ul>
202      *  <li>Native seed type: {@code int[]}.</li>
203      *  <li>Native seed size: 1391.</li>
204      * </ul>
205      */
206     WELL_44497_A(ProviderBuilder.RandomSourceInternal.WELL_44497_A),
207     /**
208      * Source of randomness is {@link org.apache.commons.rng.core.source32.Well44497b}.
209      * <ul>
210      *  <li>Native seed type: {@code int[]}.</li>
211      *  <li>Native seed size: 1391.</li>
212      * </ul>
213      */
214     WELL_44497_B(ProviderBuilder.RandomSourceInternal.WELL_44497_B),
215     /**
216      * Source of randomness is {@link org.apache.commons.rng.core.source32.MersenneTwister}.
217      * <ul>
218      *  <li>Native seed type: {@code int[]}.</li>
219      *  <li>Native seed size: 624.</li>
220      * </ul>
221      */
222     MT(ProviderBuilder.RandomSourceInternal.MT),
223     /**
224      * Source of randomness is {@link org.apache.commons.rng.core.source32.ISAACRandom}.
225      * <ul>
226      *  <li>Native seed type: {@code int[]}.</li>
227      *  <li>Native seed size: 256.</li>
228      * </ul>
229      */
230     ISAAC(ProviderBuilder.RandomSourceInternal.ISAAC),
231     /**
232      * Source of randomness is {@link org.apache.commons.rng.core.source64.SplitMix64}.
233      * <ul>
234      *  <li>Native seed type: {@code Long}.</li>
235      * </ul>
236      */
237     SPLIT_MIX_64(ProviderBuilder.RandomSourceInternal.SPLIT_MIX_64),
238     /**
239      * Source of randomness is {@link org.apache.commons.rng.core.source64.XorShift1024Star}.
240      * <ul>
241      *  <li>Native seed type: {@code long[]}.</li>
242      *  <li>Native seed size: 16.</li>
243      * </ul>
244      *
245      * @deprecated Since 1.3, where it is recommended to use {@code XOR_SHIFT_1024_S_PHI}
246      * instead due to its slightly better (more uniform) output. {@code XOR_SHIFT_1024_S}
247      * is still quite usable but both are variants of the same algorithm and maintain their
248      * internal state identically. Their outputs are correlated and the two should not be
249      * used together when independent sequences are assumed.
250      */
251     @Deprecated
252     XOR_SHIFT_1024_S(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S),
253     /**
254      * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres}.
255      * This generator is equivalent to {@link #TWO_CMRES_SELECT} with the choice of the
256      * pair {@code (0, 1)} for the two subcycle generators.
257      * <ul>
258      *  <li>Native seed type: {@code Integer}.</li>
259      * </ul>
260      */
261     TWO_CMRES(ProviderBuilder.RandomSourceInternal.TWO_CMRES),
262     /**
263      * Source of randomness is {@link org.apache.commons.rng.core.source64.TwoCmres},
264      * with explicit selection of the two subcycle generators.
265      * The selection of the subcycle generator is by passing its index in the internal
266      * table, a value between 0 (included) and 13 (included).
267      * The two indices must be different.
268      * Different choices of an ordered pair of indices create independent generators.
269      * <ul>
270      *  <li>Native seed type: {@code Integer}.</li>
271      * </ul>
272      */
273     TWO_CMRES_SELECT(ProviderBuilder.RandomSourceInternal.TWO_CMRES_SELECT),
274     /**
275      * Source of randomness is {@link org.apache.commons.rng.core.source64.MersenneTwister64}.
276      * <ul>
277      *  <li>Native seed type: {@code long[]}.</li>
278      *  <li>Native seed size: 312.</li>
279      * </ul>
280      */
281     MT_64(ProviderBuilder.RandomSourceInternal.MT_64),
282     /**
283      * Source of randomness is {@link org.apache.commons.rng.core.source32.MultiplyWithCarry256}.
284      * <ul>
285      *  <li>Native seed type: {@code int[]}.</li>
286      *  <li>Native seed size: 257.</li>
287      * </ul>
288      */
289     MWC_256(ProviderBuilder.RandomSourceInternal.MWC_256),
290     /**
291      * Source of randomness is {@link org.apache.commons.rng.core.source32.KISSRandom}.
292      * <ul>
293      *  <li>Native seed type: {@code int[]}.</li>
294      *  <li>Native seed size: 4.</li>
295      * </ul>
296      */
297     KISS(ProviderBuilder.RandomSourceInternal.KISS),
298     /**
299      * Source of randomness is {@link org.apache.commons.rng.core.source64.XorShift1024StarPhi}.
300      * <ul>
301      *  <li>Native seed type: {@code long[]}.</li>
302      *  <li>Native seed size: 16.</li>
303      * </ul>
304      * @since 1.3
305      */
306     XOR_SHIFT_1024_S_PHI(ProviderBuilder.RandomSourceInternal.XOR_SHIFT_1024_S_PHI),
307     /**
308      * Source of randomness is {@link org.apache.commons.rng.core.source32.XoRoShiRo64Star}.
309      * <ul>
310      *  <li>Native seed type: {@code int[]}.</li>
311      *  <li>Native seed size: 2.</li>
312      * </ul>
313      * @since 1.3
314      */
315     XO_RO_SHI_RO_64_S(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_64_S),
316     /**
317      * Source of randomness is {@link org.apache.commons.rng.core.source32.XoRoShiRo64StarStar}.
318      * <ul>
319      *  <li>Native seed type: {@code int[]}.</li>
320      *  <li>Native seed size: 2.</li>
321      * </ul>
322      * @since 1.3
323      */
324     XO_RO_SHI_RO_64_SS(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_64_SS),
325     /**
326      * Source of randomness is {@link org.apache.commons.rng.core.source32.XoShiRo128Plus}.
327      * <ul>
328      *  <li>Native seed type: {@code int[]}.</li>
329      *  <li>Native seed size: 4.</li>
330      * </ul>
331      * @since 1.3
332      */
333     XO_SHI_RO_128_PLUS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_128_PLUS),
334     /**
335      * Source of randomness is {@link org.apache.commons.rng.core.source32.XoShiRo128StarStar}.
336      * <ul>
337      *  <li>Native seed type: {@code int[]}.</li>
338      *  <li>Native seed size: 4.</li>
339      * </ul>
340      * @since 1.3
341      */
342     XO_SHI_RO_128_SS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_128_SS),
343     /**
344      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo128Plus}.
345      * <ul>
346      *  <li>Native seed type: {@code long[]}.</li>
347      *  <li>Native seed size: 2.</li>
348      * </ul>
349      * @since 1.3
350      */
351     XO_RO_SHI_RO_128_PLUS(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_128_PLUS),
352     /**
353      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo128StarStar}.
354      * <ul>
355      *  <li>Native seed type: {@code long[]}.</li>
356      *  <li>Native seed size: 2.</li>
357      * </ul>
358      * @since 1.3
359      */
360     XO_RO_SHI_RO_128_SS(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_128_SS),
361     /**
362      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo256Plus}.
363      * <ul>
364      *  <li>Native seed type: {@code long[]}.</li>
365      *  <li>Native seed size: 4.</li>
366      * </ul>
367      * @since 1.3
368      */
369     XO_SHI_RO_256_PLUS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_256_PLUS),
370     /**
371      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo256StarStar}.
372      * <ul>
373      *  <li>Native seed type: {@code long[]}.</li>
374      *  <li>Native seed size: 4.</li>
375      * </ul>
376      * @since 1.3
377      */
378     XO_SHI_RO_256_SS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_256_SS),
379     /**
380      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo512Plus}.
381      * <ul>
382      *  <li>Native seed type: {@code long[]}.</li>
383      *  <li>Native seed size: 8.</li>
384      * </ul>
385      * @since 1.3
386      */
387     XO_SHI_RO_512_PLUS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_512_PLUS),
388     /**
389      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo512StarStar}.
390      * <ul>
391      *  <li>Native seed type: {@code long[]}.</li>
392      *  <li>Native seed size: 8.</li>
393      * </ul>
394      * @since 1.3
395      */
396     XO_SHI_RO_512_SS(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_512_SS),
397     /**
398      * Source of randomness is {@link org.apache.commons.rng.core.source32.PcgXshRr32}.
399      * <ul>
400      *  <li>Native seed type: {@code long[]}.</li>
401      *  <li>Native seed size: 2.</li>
402      * </ul>
403      * @since 1.3
404      */
405     PCG_XSH_RR_32(ProviderBuilder.RandomSourceInternal.PCG_XSH_RR_32),
406     /**
407      * Source of randomness is {@link org.apache.commons.rng.core.source32.PcgXshRs32}.
408      * <ul>
409      *  <li>Native seed type: {@code long[]}.</li>
410      *  <li>Native seed size: 2.</li>
411      * </ul>
412      * @since 1.3
413      */
414     PCG_XSH_RS_32(ProviderBuilder.RandomSourceInternal.PCG_XSH_RS_32),
415     /**
416      * Source of randomness is {@link org.apache.commons.rng.core.source64.PcgRxsMXs64}.
417      * <ul>
418      *  <li>Native seed type: {@code long[]}.</li>
419      *  <li>Native seed size: 2.</li>
420      * </ul>
421      * @since 1.3
422      */
423     PCG_RXS_M_XS_64(ProviderBuilder.RandomSourceInternal.PCG_RXS_M_XS_64),
424     /**
425      * Source of randomness is {@link org.apache.commons.rng.core.source32.PcgMcgXshRr32}.
426      * <ul>
427      *  <li>Native seed type: {@code Long}.</li>
428      * </ul>
429      * @since 1.3
430      */
431     PCG_MCG_XSH_RR_32(ProviderBuilder.RandomSourceInternal.PCG_MCG_XSH_RR_32),
432     /**
433      * Source of randomness is {@link org.apache.commons.rng.core.source32.PcgMcgXshRs32}.
434      * <ul>
435      *  <li>Native seed type: {@code Long}.</li>
436      * </ul>
437      * @since 1.3
438      */
439     PCG_MCG_XSH_RS_32(ProviderBuilder.RandomSourceInternal.PCG_MCG_XSH_RS_32),
440     /**
441      * Source of randomness is {@link org.apache.commons.rng.core.source32.MiddleSquareWeylSequence}.
442      * <ul>
443      *  <li>Native seed type: {@code long[]}.</li>
444      *  <li>Native seed size: 3.</li>
445      * </ul>
446      * @since 1.3
447      */
448     MSWS(ProviderBuilder.RandomSourceInternal.MSWS),
449     /**
450      * Source of randomness is {@link org.apache.commons.rng.core.source32.DotyHumphreySmallFastCounting32}.
451      * <ul>
452      *  <li>Native seed type: {@code int[]}.</li>
453      *  <li>Native seed size: 3.</li>
454      * </ul>
455      * @since 1.3
456      */
457     SFC_32(ProviderBuilder.RandomSourceInternal.SFC_32),
458     /**
459      * Source of randomness is {@link org.apache.commons.rng.core.source64.DotyHumphreySmallFastCounting64}.
460      * <ul>
461      *  <li>Native seed type: {@code long[]}.</li>
462      *  <li>Native seed size: 3.</li>
463      * </ul>
464      * @since 1.3
465      */
466     SFC_64(ProviderBuilder.RandomSourceInternal.SFC_64),
467     /**
468      * Source of randomness is {@link org.apache.commons.rng.core.source32.JenkinsSmallFast32}.
469      * <ul>
470      *  <li>Native seed type: {@code Integer}.</li>
471      * </ul>
472      * @since 1.3
473      */
474     JSF_32(ProviderBuilder.RandomSourceInternal.JSF_32),
475     /**
476      * Source of randomness is {@link org.apache.commons.rng.core.source64.JenkinsSmallFast64}.
477      * <ul>
478      *  <li>Native seed type: {@code Long}.</li>
479      * </ul>
480      * @since 1.3
481      */
482     JSF_64(ProviderBuilder.RandomSourceInternal.JSF_64),
483     /**
484      * Source of randomness is {@link org.apache.commons.rng.core.source32.XoShiRo128PlusPlus}.
485      * <ul>
486      *  <li>Native seed type: {@code int[]}.</li>
487      *  <li>Native seed size: 4.</li>
488      * </ul>
489      * @since 1.3
490      */
491     XO_SHI_RO_128_PP(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_128_PP),
492     /**
493      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo128PlusPlus}.
494      * <ul>
495      *  <li>Native seed type: {@code long[]}.</li>
496      *  <li>Native seed size: 2.</li>
497      * </ul>
498      * @since 1.3
499      */
500     XO_RO_SHI_RO_128_PP(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_128_PP),
501     /**
502      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo256PlusPlus}.
503      * <ul>
504      *  <li>Native seed type: {@code long[]}.</li>
505      *  <li>Native seed size: 4.</li>
506      * </ul>
507      * @since 1.3
508      */
509     XO_SHI_RO_256_PP(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_256_PP),
510     /**
511      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoShiRo512PlusPlus}.
512      * <ul>
513      *  <li>Native seed type: {@code long[]}.</li>
514      *  <li>Native seed size: 8.</li>
515      * </ul>
516      * @since 1.3
517      */
518     XO_SHI_RO_512_PP(ProviderBuilder.RandomSourceInternal.XO_SHI_RO_512_PP),
519     /**
520      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo1024PlusPlus}.
521      * <ul>
522      *  <li>Native seed type: {@code long[]}.</li>
523      *  <li>Native seed size: 16.</li>
524      * </ul>
525      * @since 1.3
526      */
527     XO_RO_SHI_RO_1024_PP(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_1024_PP),
528     /**
529      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo1024Star}.
530      * <ul>
531      *  <li>Native seed type: {@code long[]}.</li>
532      *  <li>Native seed size: 16.</li>
533      * </ul>
534      * @since 1.3
535      */
536     XO_RO_SHI_RO_1024_S(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_1024_S),
537     /**
538      * Source of randomness is {@link org.apache.commons.rng.core.source64.XoRoShiRo1024StarStar}.
539      * <ul>
540      *  <li>Native seed type: {@code long[]}.</li>
541      *  <li>Native seed size: 16.</li>
542      * </ul>
543      * @since 1.3
544      */
545     XO_RO_SHI_RO_1024_SS(ProviderBuilder.RandomSourceInternal.XO_RO_SHI_RO_1024_SS);
546 
547     /** Internal identifier. */
548     private final ProviderBuilder.RandomSourceInternal internalIdentifier;
549 
550     /**
551      * @param id Internal identifier.
552      */
553     RandomSource(ProviderBuilder.RandomSourceInternal id) {
554         internalIdentifier = id;
555     }
556 
557     /**
558      * @return the internal identifier.
559      */
560     ProviderBuilder.RandomSourceInternal getInternalIdentifier() {
561         return internalIdentifier;
562     }
563 
564     /**
565      * Checks whether the type of given {@code seed} is the native type
566      * of the implementation.
567      *
568      * @param seed Seed value.
569      * @return {@code true} if the type of {@code seed} is the native
570      * type for this RNG source.
571      */
572     public boolean isNativeSeed(Object seed) {
573         return internalIdentifier.isNativeSeed(seed);
574     }
575 
576     /**
577      * Creates a seed suitable for the implementing class represented by this random source.
578      *
579      * <p>The seed will be created as if passing a {@code null} seed to the factory method
580      * {@link #create(RandomSource, Object, Object...)}. It will satisfy the seed size and any
581      * other seed requirements for the implementing class. The seed is converted from the native
582      * type to a byte representation.</p>
583      *
584      * <p>Usage example:</p>
585      * <pre><code>
586      *  RandomSource source = ...;
587      *  byte[] seed = source.createSeed();
588      *  UniformRandomProvider rng = RandomSource.create(source, seed);
589      * </code></pre>
590      *
591      * @return the seed
592      * @since 1.3
593      */
594     public byte[] createSeed() {
595         return internalIdentifier.createSeedBytes();
596     }
597 
598     /**
599      * Creates a seed suitable for the implementing class represented by this random source
600      * using the supplied source of randomness.
601      *
602      * <p>The seed will satisfy the seed size and any other seed requirements for the
603      * implementing class.</p>
604      *
605      * <p>Usage example:</p>
606      * <pre><code>
607      *  RandomSource source = ...;
608      *  UniformRandomProvider seedRng = new JDKRandomWrapper(new SecureRandom());
609      *  byte[] seed = source.createSeed(seedRng);
610      *  UniformRandomProvider rng = RandomSource.create(source, seed);
611      * </code></pre>
612      *
613      * @param rng Source of randomness.
614      * @return the seed
615      * @since 1.3
616      */
617     public byte[] createSeed(UniformRandomProvider rng) {
618         return internalIdentifier.createSeedBytes(rng);
619     }
620 
621     /**
622      * Checks whether the implementing class represented by this random source
623      * supports the {@link org.apache.commons.rng.JumpableUniformRandomProvider
624      * JumpableUniformRandomProvider} interface. If {@code true} the instance returned
625      * by {@link #create(RandomSource)} may be cast to the interface; otherwise a class
626      * cast exception will occur.
627      *
628      * <p>Usage example:</p>
629      * <pre><code>
630      *  RandomSource source = ...;
631      *  if (source.isJumpable()) {
632      *      JumpableUniformRandomProvider rng =
633      *          (JumpableUniformRandomProvider) RandomSource.create(source);
634      *  }
635      * </code></pre>
636      *
637      * @return {@code true} if jumpable
638      * @since 1.3
639      */
640     public boolean isJumpable() {
641         return isAssignableTo(org.apache.commons.rng.JumpableUniformRandomProvider.class);
642     }
643 
644     /**
645      * Checks whether the implementing class represented by this random source
646      * supports the {@link org.apache.commons.rng.LongJumpableUniformRandomProvider
647      * LongJumpableUniformRandomProvider} interface. If {@code true} the instance returned
648      * by {@link #create(RandomSource)} may be cast to the interface; otherwise a class
649      * cast exception will occur.
650      *
651      * <p>Usage example:</p>
652      * <pre><code>
653      *  RandomSource source = ...;
654      *  if (source.isJumpable()) {
655      *      LongJumpableUniformRandomProvider rng =
656      *          (LongJumpableUniformRandomProvider) RandomSource.create(source);
657      *  }
658      * </code></pre>
659      *
660      * @return {@code true} if long jumpable
661      * @since 1.3
662      */
663     public boolean isLongJumpable() {
664         return isAssignableTo(org.apache.commons.rng.LongJumpableUniformRandomProvider.class);
665     }
666 
667     /**
668      * Determines if the implementing class represented by this random source is either the same
669      * as, or is a subclass or subinterface of, the class or interface represented
670      * by the specified {@code Class} parameter. It returns true if so; otherwise it returns
671      * false.
672      *
673      * @param type the {@code Class} object to be checked
674      * @return the boolean value indicating whether the class of this random source
675      * can be assigned to objects of the specified type
676      */
677     private boolean isAssignableTo(Class<?> type) {
678         return type.isAssignableFrom(internalIdentifier.getRng());
679     }
680 
681     /**
682      * Creates a random number generator with a random seed.
683      *
684      * <p>Usage example:</p>
685      * <pre><code>
686      *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT);
687      * </code></pre>
688      * <p>or, if a {@link RestorableUniformRandomProvider "save/restore"} functionality is needed,</p>
689      * <pre><code>
690      *  RestorableUniformRandomProvider rng = RandomSource.create(RandomSource.MT);
691      * </code></pre>
692      *
693      * @param source RNG type.
694      * @return the RNG.
695      *
696      * @see #create(RandomSource,Object,Object[])
697      */
698     public static RestorableUniformRandomProvider create(RandomSource source) {
699         return ProviderBuilder.create(source.getInternalIdentifier());
700     }
701 
702     /**
703      * Creates a random number generator with the given {@code seed}.
704      *
705      * <p>Usage example:</p>
706      * <pre><code>
707      *  UniformRandomProvider rng = RandomSource.create(RandomSource.TWO_CMRES_SELECT, 26219, 6, 9);
708      * </code></pre>
709      *
710      * <p>Valid types for the {@code seed} are:</p>
711      *  <ul>
712      *   <li>{@code Integer} (or {@code int})</li>
713      *   <li>{@code Long} (or {@code long})</li>
714      *   <li>{@code int[]}</li>
715      *   <li>{@code long[]}</li>
716      *   <li>{@code byte[]}</li>
717      *  </ul>
718      *
719      * <p>Notes:</p>
720      * <ul>
721      *  <li>
722      *   When the seed type passed as argument is more complex (i.e. more
723      *   bits can be independently chosen) than the generator's
724      *   {@link #isNativeSeed(Object) native type}, the conversion of a
725      *   set of different seeds will necessarily result in the same value
726      *   of the native seed type.
727      *  </li>
728      *  <li>
729      *   When the native seed type is an array, the same remark applies
730      *   when the array contains more bits than the state of the generator.
731      *  </li>
732      *  <li>
733      *   When the {@code seed} is {@code null}, a seed of the native type
734      *   will be generated. If the native type is an array, the generated
735      *   size is limited a maximum of 128.
736      *  </li>
737      * </ul>
738      *
739      * @param source RNG type.
740      * @param seed Seed value.  It can be {@code null} (in which case a
741      * random value will be used).
742      * @param data Additional arguments to the implementation's constructor.
743      * Please refer to the documentation of each specific implementation.
744      * @return the RNG.
745      * @throws UnsupportedOperationException if the type of the {@code seed}
746      * is invalid.
747      * @throws IllegalStateException if data is missing to initialize the
748      * generator implemented by the given {@code source}.
749      *
750      * @see #create(RandomSource)
751      */
752     public static RestorableUniformRandomProvider create(RandomSource source,
753                                                          Object seed,
754                                                          Object... data) {
755         return ProviderBuilder.create(source.getInternalIdentifier(), seed, data);
756     }
757 
758     /**
759      * Creates a number for use as a seed.
760      *
761      * @return a random number.
762      */
763     public static int createInt() {
764         return SeedFactory.createInt();
765     }
766 
767     /**
768      * Creates a number for use as a seed.
769      *
770      * @return a random number.
771      */
772     public static long createLong() {
773         return SeedFactory.createLong();
774     }
775 
776     /**
777      * Creates an array of numbers for use as a seed.
778      *
779      * @param n Size of the array to create.
780      * @return an array of {@code n} random numbers.
781      */
782     public static int[] createIntArray(int n) {
783         return SeedFactory.createIntArray(n);
784     }
785 
786     /**
787      * Creates an array of numbers for use as a seed.
788      *
789      * @param n Size of the array to create.
790      * @return an array of {@code n} random numbers.
791      */
792     public static long[] createLongArray(int n) {
793         return SeedFactory.createLongArray(n);
794     }
795 
796     /**
797      * Wraps the given {@code delegate} generator in a new instance that
798      * does not allow access to the "save/restore" functionality.
799      *
800      * @param delegate Generator to which calls will be delegated.
801      * @return a new instance whose state cannot be saved or restored.
802      */
803     public static UniformRandomProvider unrestorable(final UniformRandomProvider delegate) {
804         return new UniformRandomProvider() {
805             /** {@inheritDoc} */
806             @Override
807             public void nextBytes(byte[] bytes) {
808                 delegate.nextBytes(bytes);
809             }
810 
811             /** {@inheritDoc} */
812             @Override
813             public void nextBytes(byte[] bytes,
814                                   int start,
815                                   int len) {
816                 delegate.nextBytes(bytes, start, len);
817             }
818 
819             /** {@inheritDoc} */
820             @Override
821             public int nextInt() {
822                 return delegate.nextInt();
823             }
824 
825             /** {@inheritDoc} */
826             @Override
827             public int nextInt(int n) {
828                 return delegate.nextInt(n);
829             }
830 
831             /** {@inheritDoc} */
832             @Override
833             public long nextLong() {
834                 return delegate.nextLong();
835             }
836 
837             /** {@inheritDoc} */
838             @Override
839             public long nextLong(long n) {
840                 return delegate.nextLong(n);
841             }
842 
843             /** {@inheritDoc} */
844             @Override
845             public boolean nextBoolean() {
846                 return delegate.nextBoolean();
847             }
848 
849             /** {@inheritDoc} */
850             @Override
851             public float nextFloat() {
852                 return delegate.nextFloat();
853             }
854 
855             /** {@inheritDoc} */
856             @Override
857             public double nextDouble() {
858                 return delegate.nextDouble();
859             }
860 
861             /** {@inheritDoc} */
862             @Override
863             public String toString() {
864                 return delegate.toString();
865             }
866         };
867     }
868 }