001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.rng.simple;
018
019import org.apache.commons.rng.UniformRandomProvider;
020import org.apache.commons.rng.RestorableUniformRandomProvider;
021import org.apache.commons.rng.simple.internal.ProviderBuilder;
022import org.apache.commons.rng.simple.internal.SeedFactory;
023
024/**
025 * This class provides the API for creating generators of random numbers.
026 *
027 * <p>Usage examples:</p>
028 * <pre><code>
029 *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT);
030 * </code></pre>
031 * or
032 * <pre><code>
033 *  final int[] seed = new int[] { 196, 9, 0, 226 };
034 *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed);
035 * </code></pre>
036 * or
037 * <pre><code>
038 *  final int[] seed = RandomSource.createIntArray(256);
039 *  UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed);
040 * </code></pre>
041 * where the first argument to method {@code create} is the identifier
042 * of the generator's concrete implementation, and the second the is the
043 * (optional) seed.
044 *
045 * <p>
046 * In the first form, a random seed will be {@link SeedFactory generated
047 * automatically}; in the second form, a fixed seed is used; a random seed
048 * is explicitly generated in the third form.
049 * </p>
050 *
051 * <p>
052 * Seeding is the procedure by which a value (or set of values) is
053 * used to <i>initialize</i> a generator instance.
054 * The requirement that a given seed will always result in the same
055 * internal state allows to create different instances of a generator
056 * that will produce the same sequence of pseudo-random numbers.
057 * </p>
058 *
059 * <p>
060 * The type of data used as a seed depends on the concrete implementation
061 * as some types may not provide enough information to fully initialize
062 * the generator's internal state.
063 * <br>
064 * The reference algorithm's seeding procedure (if provided) operates
065 * on a value of a (single) <i>native</i> type:
066 * Each concrete implementation's constructor creates an instance using
067 * the native type whose information contents is used to set the
068 * internal state.
069 * <br>
070 * When the seed value passed by the caller is of the native type, it is
071 * expected that the sequences produced will be identical to those
072 * produced by other implementations of the same reference algorithm.
073 * <br>
074 * However, when the seed value passed by the caller is not of the native
075 * type, a transformation is performed by this library and the resulting
076 * native type value will <i>not</i> contain more information than the
077 * original seed value.
078 * If the algorithm's native type is "simpler" than the type passed by
079 * the caller, then some (unused) information will even be lost.
080 * <br>
081 * The transformation from non-native to native seed type is arbitrary,
082 * as long as it does not reduce the amount of information required by
083 * the algorithm to initialize its state.
084 * The consequence of the transformation is that sequences produced
085 * by this library may <i>not</i> be the same as the sequences produced
086 * by other implementations of the same algorithm!
087 * </p>
088 *
089 * <p>
090 * For each algorithm, the Javadoc mentions the "ideal" size of the seed,
091 * meaning the number of {@code int} or {@code long} values that is neither
092 * too large (i.e. some of the seed is useless) or too small (i.e. an
093 * internal procedure will fill the state with redundant information
094 * computed from the given seed).
095 * </p>
096 *
097 * <p>
098 * Note that some algorithms are inherently sensitive to having too low
099 * 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 */
159public 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}